簡體   English   中英

ForkJoinPool.commonPool()和新的ForkJoinPool(availableCPU-1)有什么區別?

[英]What is the difference between ForkJoinPool.commonPool() and new ForkJoinPool(availableCPU - 1)?

在我的代碼中,我有一個包含靜態最終變量的類

private static final ForkJoinPool pool = new ForkJoinPool(availableCPUs - 1);

我有一個長時間運行的任務提交給池,它將占用所有CPU資源。 提交的任何其他任務將被掛起。 但是,當我切換為創建公共池時

private static final ForkJoinPool pool = ForkJoinPool.commonPool();

所有任務都可以提交並執行。

我只是想知道這兩段代碼之間的區別。 commonPool()仍然調用new ForkJoinPool()並傳遞availableCPUs - 1 commonPool() availableCPUs - 1

我還注意到, commonPool()使用類型為SafeForkJoinWorkerThreadFactory的工廠,而new ForkJoinPool()使用ForkJoinPool$DefaultForkJoinWorkerThreadFactory 這有關系嗎?

非常感謝你!

文檔說:

默認情況下,公共池是使用默認參數構造的。

ForkJoinPool()

使用默認線程工廠 ,無UncaughtExceptionHandler和非異步LIFO處理模式,創建一個並行度等於Runtime.availableProcessors()ForkJoinPool

那么,是什么讓您認為new ForkJoinPool(availableCPUs - 1)ForkJoinPool.commonPool()將是相同大小的池?

如果只有2個CPU,那么availableCPUs - 1 CPU availableCPUs - 1表示您正在創建一個1個線程的池,即它一次只能處理一個任務,因此長時間運行的任務將阻止所有其他任務。

但是,使用2個CPU, availableProcessors()意味着您將獲得一個具有2個線程的公用池,即,它可以在處理一個長期運行的任務時處理其他任務。

我想我知道了。

ForkJoin維護兩種類型的隊列:每個工作線程一個普通的入站隊列和工作線程隊列。 所有工作線程將首先從常規入站隊列中獲取並填充其工作線程。 一個工作線程完成其工作隊列中的所有任務后,將嘗試從其他工作線程中竊取。 如果沒有其他任務要從其他工作線程中竊取,則工作線程將再次從常規入站隊列中獲取。

但是,對於公共池,主線程也將幫助處理任務。 但是,主線程沒有工作隊列。 因此,完成一項任務后,主線程將能夠從常規入站隊列中獲取。

由於默認情況下,ForkJoin隊列為LIFO,因此主線程將能夠提取最后提交的任務。

暫無
暫無

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

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