ForkJoinTask
的{{3}}说:
[R] eturns(连接)应该在最里面进行。例如,a.fork(); b.fork(); b.join(); a.join();可能比加入之前的b更有效率。
我无法理解为什么(以及在何种情况下)join()
s的顺序很重要,假设我需要加入a
和< / strong> b
并在继续我的计算之前得到他们的结果。
具体来说,我有几十个fork()
ed任务,我需要等待所有的任务返回结果;很像invokeAll()
会做的,但我仍然可以在fork()
之后但在join()
之前执行一些工作,所以我实现了像joinAll()
之类的东西只有在我调用时才会被调用我知道如果没有分叉任务的结果,我就无法继续。
问题是,如何实施joinAll()
?此代码在任务中实际调用join()
的顺序是否重要?
答案 0 :(得分:1)
在准备ForkJoin-Framework进行演讲时,我也偶然发现了文档中的这一说法,并想知道为什么会这样。
首先,我想指出的是,我对您的问题没有确切的答案,但想分享一下我发现的内容:
在Doug Lea(http://gee.cs.oswego.edu/dl/papers/fj.pdf)撰写的原始论文中,第2.1节更详细地描述了他的Work-Stealing算法的实现:由工作线程(使用fork
生成的子任务是插入自己的双端队列。辅助线程处理其自己的双端队列LIFO (最年轻),而辅助线程则从其他双端队列FIFO(最早的)中窃取。
然后我认为重要的一点是:“当工作线程遇到join
操作时,它处理其他任务(如果可用),直到发现目标任务已完成(通过isDone)。否则所有任务都会运行完成而不会阻塞。”
因此,首先join
处理工作人员本身接下来将要处理的任务,而不是join
处理可能从其他工作人员窃取的其他任务,效率更高。否则,由于潜在的上下文切换和锁争用,可能会有更多的线程管理开销。
至少对我来说,这种推理对于JavaDoc中的描述是有意义的。