在 Java 並發編程中,線程池是管理線程生命週期、控制併發數量的關鍵組件。Java 通過 Executors 工廠類提供了四種常用的線程池實現,但它們的底層核心均是 ThreadPoolExecutor。要真正掌握線程池的行為,必須先理解 ThreadPoolExecutor 的核心參數與工作機制。
ThreadPoolExecutor 的構造函數定義了以下關鍵屬性,它們共同決定了線程池的動態行為:
corePoolSize 時,空閒線程在被回收前的最大等待時長。| 隊列類型 | 特性 | 擴容行為 | 典型應用場景 |
|---|---|---|---|
SynchronousQueue |
無容量,直接提交。生產者必須等待消費者取走任務 | 無空閒線程時嘗試創建新線程,達到 maximumPoolSize 後拒絕 |
快速處理短任務,newCachedThreadPool |
ArrayBlockingQueue |
有界陣列隊列,構造時需指定容量 | 1. t < core → 新建線程 2. t ≥ core 且隊列未滿 → 入隊 3. t ≥ core 且隊列滿 → 新建線程 4. t ≥ max → 拒絕 |
需限制併發與排隊的場景 |
LinkedBlockingQueue |
無界鏈表隊列(預設 Integer.MAX_VALUE) | 線程數 < core 時新建,否則入隊。注意:可能導致 OOM | 任務量平穩、不希望拒絕任務的場景,newFixedThreadPool |
PriorityBlockingQueue |
無界優先級隊列,按任務優先級排序 | 同無界隊列,但執行順序由優先級決定 | 需按優先級處理任務的場景 |
AbortPolicy(預設):直接拋出 RejectedExecutionExceptionCallerRunsPolicy:由調用者線程執行任務,提供背壓效果DiscardOldestPolicy:丟棄隊列中最舊的任務,嘗試重新提交DiscardPolicy:靜默丟棄任務若內置策略無法滿足業務需求,可實現 RejectedExecutionHandler 接口自定義邏輯。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
特點:corePoolSize == maximumPoolSize,線程數固定不變;使用無界隊列,任務提交過快時隊列會無限增長,存在 OOM 風險。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
特點:退化版固定線程池,僅單線程串行執行,保證任務按 FIFO/LIFO/優先級順序執行。同樣使用無界隊列,有 OOM 風險。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
特點:corePoolSize = 0,maximumPoolSize = Integer.MAX_VALUE;無任務時不創建線程,任務來臨時復用空閒線程或創建新線程;空閒線程 60 秒後回收。大量突發任務時會創建大量線程,極易耗盡系統資源。
支持延遲執行與周期性任務,內部使用 DelayedWorkQueue(基於堆的優先級隊列),此處不再贅述。
FixedThreadPool 和 CachedThreadPool,因其隱含 OOM 風險。ArrayBlockingQueue)。CallerRunsPolicy 實現背壓,或自定義策略記錄日誌、持久化任務。ThreadFactory 設置有意義的線程名稱(如 order-process-1),便於排查問題。深入理解 ThreadPoolExecutor 的參數交互關係,是編寫高性能、穩定 Java 併發應用的基石。建議在項目中封裝統一的線程池配置類,集中管理所有業務線程池。