2012-04-11 42 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實現。

每一個新的任務(或子任務)被創建時,它推到其自己的隊列的頭 。當一項任務完成一項任務並與另一項尚未完成的任務一起執行加入 時,它會很聰明地工作。該 線程彈出從其隊列的頭一個新的任務,開始執行 而不是睡覺(以等待另一個任務完成)。 事實上,如果一個線程隊列爲空,則彈出線從屬於另一個線程隊列的尾部 任務。這是 沒什麼,但工作竊取算法。