2012-04-11 46 views
3

在Doug Lea的论文 “一个Java fork/join框架” 的细节:关于fork-join框架

http://gee.cs.oswego.edu/dl/papers/fj.pdf

在2.1工作窃取他说:

当工人线程遇到连接操作,它处理其他任务 ,如果有的话,直到目标任务是发现有 完成(通过isDone)。否则,所有任务将运行至完成而没有 阻止。

所以谁能告诉我具体在哪里,这些“其他任务”从何而来?他们是否来自其他工作线程的任务队列?这是否意味着每当一个工作线程遇到连接调用时,它就会继续“从其他线程中窃取任务”而不是“跳到其自己队列中的其他任务”?

+1

如果您想了解更多关于这方面的细节,您可能需要阅读有关偷工作的西尔克论文。 java版本与leisersons的工作并不完全相同,但非常相似,并且leiserson更详细地描述了它。 – Voo 2012-04-11 09:36:09

回答

2

的“其他任务”可能来自它自己的双端队列中时,有尚未完成的任务,其他线程的双端,或新请求的提交队列。

该加入()是一个相当困难的过程。它涉及任务控制,即在任务处于活动状态并暂停等待某些事件时控制任务的能力。在应用程序中执行此操作通常不起作用。 (操作系统做得很好,Cilk,JCilk通过使用编译器/运行时来完成。)Doug Lea在连接陷入工作线程时使用“延续线程”。

+0

据我了解deques(双端队列)的工作方式,deque只支持三种操作:“pop”,“push”和“steal”(或从中偷取),并且所有这些操作都只能工作无论是头部任务还是队列的尾部任务。在这种情况下,工作线程如何跳过头部任务(假设头部任务遇到“连接”操作)并继续执行“同一队列中的其他待处理任务”,然后返回到跳过的任务? – njzhxf 2012-04-12 05:43:07

+0

该deque的顶部只被其他线程用来窃取工作。双端队列的底部仅由当前线程用于添加/轮询任务。当前线程轮询它时删除一个任务。如果该任务发出join(),则当前线程或“延续线程”会在双端队列底部查找任务。看代码。这是令人难以置信的复杂。特别是提出的Java8版本。 – edharned 2012-04-12 13:04:45

0

Fork/Join framework每个工作线程都有一个工作队列,这 使用的Deque实现。

每一个新的任务(或子任务)被创建时,它推到其自己的队列的头 。当一项任务完成一项任务并与另一项尚未完成的任务一起执行加入 时,它会很聪明地工作。该 线程弹出从其队列的头一个新的任务,开始执行 而不是睡觉(以等待另一个任务完成)。 事实上,如果一个线程队列为空,则弹出线从属于另一个线程队列的尾部 任务。这是 没什么,但工作窃取算法。