我有一個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。它只是產生新的線程來解決僵局?
更正:final ExecutorService executorSer = new ForkJoinPool(SIZE);是我用過的。 @iullianr:謝謝你指出。 – Patt