簡體   English   中英

當線程數少於invokeAll()的任務數時會發生什么?

[英]What will happen when there are less threads than number of tasks for invokeAll()?

我有以下代碼:

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                                                10, // corePoolSize
                                                10, // maximumPoolSize
                                                10, // keepAliveTime
                                                TimeUnit.SECONDS, 
                                                new LinkedBlockingQueue<>()
                                        );

final List<Callable<MyResponse>> tasks = new ArrayList<>();
final CountDownLatch latch = new CountDownLatch(concurrency);

for (int i = 0; i < 50; i++) {
    tasks.add(() -> {
        latch.countDown();
        latch.await();

        return getResponse(); // Returns a MyResponse object.
    });
}

final List<Future<ThrottleResponse>> futures = threadPoolExecutor.invokeAll(tasks);

有50個任務,但只有10個線程可用。 根據我的測試結果,該代碼將永遠運行,這是我無法理解的。

invokeAll方法會怎樣? 該代碼中是否有死鎖,為什么? 我認為threadPoolExecutor會將待處理的任務放在LinkedBlockingQueue並從隊列中輪詢以執行任務,因此應該沒有死鎖嗎?

執行程序服務的正常行為是在池中的每個可用工作程序上啟動任務,並將其他任務放在隊列中以等待工作程序可用。

您要做的是編寫直到所有其他任務都開始才能完成的任務。 由於您有10個工作人員,因此前10個任務每個都從一個工作人員開始....然后等待。 前10個不能完成,因為它們正在等待其他任務開始,而其他任務也不能啟動,因為執行者正在等待工人釋放...直到前10個中的一個都不會發生任務完成。 僵局。


您評論了:

我認為threadPoolExecutor會將待處理的任務放在LinkedBlockingQueue中,並從隊列中輪詢以執行任務,因此應該沒有死鎖嗎?

所有任務都正確排隊。 問題在於任務排隊后本身在做什么? 請參閱上面的說明。


解決方案:

  • 不要將您的任務設計為等待其他任務開始。 (從您的示例中並不清楚為什么要這樣做,但是我懷疑這是否確實必要。)

  • 如果必須等待其他任務開始,請增加線程池大小,使其足夠大以同時運行所有任務。

因為每個任務都在“ latch.await();”上被阻止,所以LinkedBlockingQueue <>中排隊的任務將永遠不會有運行的機會。 造成僵局。 您應該在每個任務中使用latch.countDown()。 但是在主線程中運行閂鎖。

暫無
暫無

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

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