面試官:如何確保動態線程池任務都執行完?
在 Java 并發編程中,線程池是提高系統吞吐量和響應速度的重要工具。
而是在高并發場景下,動態線程池(程序運行期間動態調整線程池參數而無需重啟程序的技術)被廣泛應用。然而,如何確保動態線程池中的所有任務都執行完畢,是一個常見的面試問題,也是實際開發中必須解決的關鍵問題。
所以,本文將深入探討幾種常見的方法,幫助開發者在實際項目中優雅地處理這個問題。
方法一:CountDownLatch
使用 CountDownLatch 來跟蹤任務的完成情況,實現代碼如下:
// 動態線程池
@Autowired
@Qualifier("dtpExecutor1")
private DtpExecutor dtpExecutor;
@RequestMapping("isDone")
public String isDone() throws InterruptedException {
// 申請計數器
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
dtpExecutor.submit(() -> {
try {
Thread.sleep(1000);
System.out.println("Task executed by " + Thread.currentThread().getName());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
latch.countDown(); // 任務完成,計數器減1
}
});
}
// 等待所有任務完成
latch.await();
return"ok";
}關鍵點:
- CountDownLatch:初始化時指定任務數量。每個任務完成后調用 countDown(),主線程調用 await() 等待所有任務完成。
- 適用場景:適用于需要精確控制任務完成狀態的場景,比如批處理任務、數據聚合等。
注意:CountDownLatch 是一次性的,不能重復使用;如果需要重復使用,可以考慮 CyclicBarrier。
方法二:CompletableFuture
從 Java 8 開始,CompletableFuture 提供了更強大的異步編程能力。它不僅支持 Future 的功能,還支持任務編排、組合、異常處理等高級特性。使用 CompletableFuture,可以更方便地管理多個異步任務的執行,并確保所有任務都完成。
我們可以借助 CompletableFuture 提供了 allOf() 方法,可以等待所有任務完成,具體實現代碼如下:
// 動態線程池
@Autowired
@Qualifier("dtpExecutor1")
private DtpExecutor dtpExecutor;
@RequestMapping("isDone")
public String isDone() {
// 1.任務一
CompletableFuture future = CompletableFuture.runAsync(() -> {
// 執行業務邏輯
}, dtpExecutor);
// 2.任務二
CompletableFuture future2 = CompletableFuture.runAsync(() -> {
// 執行業務邏輯
}, dtpExecutor);
// 等待所有任務完成
CompletableFuture<Void> allTask = CompletableFuture.allOf(future, future2);
// 阻塞直到全部完成(無需結果)
allTask.join();
return"ok";
}關鍵點:
- CompletableFuture.runAsync() :異步執行任務,無任何返回值。指定動態線程池,避免使用默認的 ForkJoinPool。
- allOf() :等待所有任務完成。返回一個 CompletableFuture,調用 join() 或 get() 會阻塞,直到所有任務完成。
- join() :類似于 get(),但不會拋出檢查異常,更適合在流式操作中使用。
小結
確保動態線程池中的所有任務都執行完畢,本文介紹了兩種常見的方法:
- CountDownLatch:適用于需要精確控制任務完成狀態的場景。
- CompletableFuture:適用于復雜異步任務編排、批量任務管理、異常處理和超時控制。
最后:面試官問這個問題,避免回答過于八股化和 AI 化。因此,在回答時,可以結合自己的具體項目模塊實現來回答,要用自己的語言(非標準答案)表達出來。


































