JavaDoc ForkJoinTask
说:
[R]eturns (joins) should be performed innermost-first. For example, a.fork(); b.fork(); b.join(); a.join(); is likely to be substantially more efficient than joining a before b.
假设我需要加入 a
,我不太明白为什么(以及在哪些情况下)join()
的顺序很重要> 和 b
并在继续计算之前获取它们的结果。
具体来说,我有几十个 fork()
ed 任务,我需要等待全部返回结果;很像 invokeAll()
会做的,但我仍然可以在 fork()
之后但在 join()
之前执行一些工作,所以我实现了诸如 joinAll()
之类的东西,只有当我知道如果没有 fork 任务的结果我就无法继续时,才会调用它。
问题是,这个joinAll()
应该如何实现呢?此代码实际对任务调用 join()
的顺序重要吗?
最佳答案
在为讲座准备 ForkJoin 框架时,我也在文档中偶然发现了这个声明,并想知道为什么会这样。
首先,我想指出,我对您的问题没有明确的答案,但想分享我的发现:
在 Doug Lea ( http://gee.cs.oswego.edu/dl/papers/fj.pdf ) 撰写的原始论文中,第 2.1 节更详细地描述了他对 Work-Stealing 算法的实现:工作线程生成的子任务(使用 fork
)被推送到自己的双端队列。工作线程处理它们的自己的双端队列 LIFO(最年轻的优先),而工作线程则从其他双端队列 FIFO 中窃取(最旧的优先)。
然后我认为重要的部分是:“当工作线程遇到 join
操作时,它会处理其他任务(如果可用),直到目标任务被注意到已完成(通过 isDone)。否则所有任务都会在不阻塞的情况下运行完成。”
因此,首先加入
工作人员本身接下来要处理的任务会更有效,而不是加入
可能从其他人那里窃取的其他任务 worker 。否则,由于潜在的上下文切换和锁争用,可能会产生更多的线程管理开销。
至少对我来说,这种推理对于 JavaDoc 中的描述是有意义的。
关于java - ForkJoinTask : Order of join()-ing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50757332/