java - ForkJoinTask : Order of join()-ing

标签 java java.util.concurrent fork-join forkjoinpool

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/

相关文章:

Java List<int []> 未正确填充

java - 套接字的多线程问题

java - 混淆java中的 "==null"和 "==" ""?

java - ThreadPoolExecutor 和队列

java - 查找代码不起作用的测试用例

java - 对 getter/setter 或 AtomicReference 使用 synhronize

Java fork/join 框架逻辑

multithreading - 配置 Fork 加入线程池

java - 在 Java 7+ ForkJoinPool 中,是否可以取消任务和所有子任务?

java - 使用 Fork-Join 时静态变量的使用