[英]What is the thread rejection policy of ForkJoinPool.commonPool()?
[英]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
。 這有關系嗎?
非常感謝你!
文檔說:
默認情況下,公共池是使用默認參數構造的。
使用默認線程工廠 ,無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.