[英]What is the difference between ForkJoinPool.commonPool() and new ForkJoinPool(availableCPU - 1)?
[英]Difference between ForkJoinPool and normal ExecutionService?
我讀了一篇有關Java 7中fork-join框架的精彩文章,其想法是,使用ForkJoinPool
和ForkJoinTask
,池中的線程可以從其他任務中獲取子任務,因此可以使用更少的線程來處理更多任務任務。
然后,我嘗試使用普通的ExecutorService
進行相同的工作,發現我無法分辨兩者之間的區別,因為當我向池中提交新任務時,該任務將在另一個可用線程上運行。
我可以告訴的唯一區別是,如果我使用ForkJoinPool
,則不需要將池傳遞給任務,因為可以調用task.fork()
使其在另一個線程上運行。 但是,使用普通的ExecutorService
,我必須將池傳遞給任務,或者將其設為靜態,因此在任務內部,我可以調用pool.submit(newTask)
我想念什么嗎?
(您可以從https://github.com/freewind/fork-join-test/tree/master/src查看實時代碼)
盡管ForkJoinPool
實現了ExecutorService
,但從概念ForkJoinPool
它與“常規”執行程序不同。
如果您的任務產生了更多的任務並等待它們完成,例如,通過調用
executor.invoke(new Task()); // blocks this thread until new task completes
在常規執行程序服務中,等待其他任務完成將阻塞當前線程。 有兩種可能的結果:如果您的執行服務具有固定數量的線程 ,則如果最后一個正在運行的線程等待另一個任務完成,則它可能會死鎖。 如果執行程序根據需要動態創建新線程,則線程數可能會激增,最終您將擁有成千上萬個可能導致飢餓的線程。
相反,fork / join框架在此期間重用線程來執行其他任務,因此盡管線程數是固定的,它也不會死鎖:
new MyForkJoinTask().invoke();
因此,如果您有可以遞歸解決的問題,請考慮使用ForkJoinPool
因為您可以輕松地將一級遞歸ForkJoinTask
為ForkJoinTask
。
只需檢查示例中正在運行的線程數即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.