我想通過一個方法提交Runnable
任務到ForkJoinPool:帶有非遞歸任務的Java ForkJoinPool,是否可以竊取工作?
forkJoinPool.submit(Runnable task)
請注意,我用的JDK 7
引擎蓋下,他們轉變成ForkJoinTask對象。 我知道ForkJoinPool是有效的,當一個任務被遞歸分割成小的時候。
問:
是否工作竊取仍處於ForkJoinPool工作,如果沒有遞歸?
在這種情況下值得嗎?
更新1: 任務很小,可能不平衡。即使是嚴格相等的任務,諸如上下文切換,線程調度,停車,頁面丟失等等也會導致不平衡。
更新2: Doug Lea的該Concurrency JSR-166 Interest組中寫道,通過給這個一個提示:
這也大大提高了產量,當所有任務異步提交到池 而不是分叉,這將成爲一種合理的 構造actor框架的方式,以及許多其他可能使用ThreadPoolExecutor的普通服務。
我認爲,當談到合理的小型CPU限制任務時,由於這種優化,ForkJoinPool是最佳選擇。重點是這些任務已經很小,不需要遞歸分解。 工作偷竊工作,無論是大型還是小型任務 - 任務可以由另一名自由工人從繁忙工人的Deque尾巴抓取。
更新3: Scalability of ForkJoinPool - 由阿卡隊乒乓的基準顯示出巨大的效果。
儘管如此,要更有效地應用ForkJoinPool,還需要進行性能調整。
我已經想過這個我自己,我想這是你提到的線程的停車和鎖定。這就是爲什麼我認爲ring buffers(disruptor)比unwrapped fork join更快(至少對於我的非遞歸事件任務)。 –
@Adam Gent我們也使用了Disruptor - 它速度驚人。是的,RingBuffer的想法應用於許多現代數據結構中。但是,它們在使用情況上有所不同:1. Disruptor使用1個線程1用戶模型進行流水線操作,但無法竊取工作,而2. FJ是一羣工作人員 - 工作分佈在多個線程(m:n)中。 –
我很熟悉fj-rb的差異,但我認爲他們都可能會減少鎖定,但我不是專家。 –