簡體   English   中英

ForkJoinPool和常規ExecutionService之間的區別?

[英]Difference between ForkJoinPool and normal ExecutionService?

我讀了一篇有關Java 7中fork-join框架的精彩文章,其想法是,使用ForkJoinPoolForkJoinTask ,池中的線程可以從其他任務中獲取子任務,因此可以使用更少的線程來處理更多任務任務。

然后,我嘗試使用普通的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因為您可以輕松地將一級遞歸ForkJoinTaskForkJoinTask

只需檢查示例中正在運行的線程數即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM