2016-02-26 93 views
2

我有一個ExecutorService的創建如下 -的ExecutorService和ForkJoinPool

ExecutorService executorSer = Executors.newFixedThreadPool(SIZE); 

我有元件(LIST)和操作(稱爲A),我需要應用在此列表中的每個元件上的列表。該列表可以包含1到1000之間的任意數量的元素。 該操作的類型爲Callable。 在Operation-A內部,它調用了2個其他服務B和C. B和C也作爲異步操作運行並提交給相同的線程池。

CompletionService<T> completionService = new ExecutorCompletionService<T>(executorSer); 
completionService.submit(A) // this returns a Future<T> 

現在我有未來的名單,我遍歷得到()結果:

我有如下會爲每個異步任務並行執行這一點。

如果我有一個非常大的線程池和LIST中的少量元素,一切正常。 但是,如果線程池SIZE很小並且LIST大小很大,我會遇到死鎖。 這是因爲所有Operation-A請求都很快提交併佔用線程池中的所有線程。並且每個操作-A在其提交的操作B和C的Future.get()上被阻止。操作B和C任務只是坐在隊列中等待獲得一個線程。

因此,爲了解決這個問題,我改用了ForkJoinPool。我簡單地更換的newFixedThreadPool與ForkJoinPool如下

ExecutorService executorSer = new ForkJoinPool(SIZE); 

,離開了其餘代碼相同。

這解決了我的問題。如果線程池SIZE很小並且LIST大小很大,現在沒有死鎖。 我的問題是,爲什麼? 此外,當我打印線程名稱,我看到線程數大於SIZE。它只是產生新的線程來解決僵局?

+0

更正:final ExecutorService executorSer = new ForkJoinPool(SIZE);是我用過的。 @iullianr:謝謝你指出。 – Patt

回答

0

java.util.concurrent.Executors類中沒有Executors.ForkJoinPool(SIZE)方法。但是,創建ForkJoinPool的方法有Executors.newWorkStealingPool(int parallelism)。作爲Java API被提:

的並行級別對應於線程 的最大數量的積極參與,或可搞的,任務處理。 線程的實際數量可能會動態增長和減少。

有你的答案。您提供的參數不是執行程序將管理的實際線程的最大數量(例如FixedThreadPool執行程序就是這種情況)。

+0

我已經使用了以下,它的工作原理。 SIZE意味着什麼?這是否意味着在給定的時間系統中可以有最多的SIZE線程數?最終ExecutorService executorSer =新的ForkJoinPool(SIZE); – Patt

+0

它表示執行程序要使用的工作線程數。爲了不創建大量的線程,如果它們沒有足夠的機器上的處理器,建議將您的值設置爲Runtime.availableProcessors()以便不會並行運行 – iullianr