執行緒池是 Java 併發程式設計的核心基礎設施,合理使用能顯著降低執行緒建立/銷毀開銷、控制併發度、提升系統穩定性。本文從架構圖解、核心參數、任務排隊機制、執行流程、池大小設定策略五個維度,系統剖析 ThreadPoolExecutor 及 Executors 工廠方法的原理與實戰應用。

核心組件:
newSingleThreadExecutor() — 單執行緒序列化執行ExecutorService pool = Executors.newSingleThreadExecutor();
for (int i = 1; i <= 3; i++) pool.execute(new MyThread("Task-" + i));
pool.shutdown();
輸出:所有任務由同一執行緒 pool-1-thread-1 依序執行,保證任務順序性、無併發衝突。
newFixedThreadPool(3) — 固定大小執行緒池ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) pool.execute(new MyThread("Task-" + i));
pool.shutdown();
輸出:3 個執行緒輪流處理 5 個任務,併發度固定,適合負載穩定的業務。
newCachedThreadPool() — 可緩存執行緒池ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 1; i <= 5; i++) pool.execute(new MyThread("Task-" + i));
pool.shutdown();
輸出:每個任務獨立執行緒並發執行(最多 5 線程),空閒 60 秒自動回收,適合大量短期非同步任務。
newScheduledThreadPool(2) — 定時/週期性任務ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.scheduleAtFixedRate(() -> System.out.println("Task A"), 1000, 2000, TimeUnit.MILLISECONDS);
pool.scheduleAtFixedRate(() -> System.out.println("Task B"), 1000, 2000, TimeUnit.MILLISECONDS);
兩個獨立週期任務互不干擾,精確按排程執行。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
| 參數 | 含義 | 關鍵影響 |
|---|---|---|
corePoolSize | 核心執行緒數(常駐) | 即使閒置也不會回收(除非 allowCoreThreadTimeOut(true)) |
maximumPoolSize | 最大執行緒數上限 | 佇列滿時才會擴容至上限 |
keepAliveTime | 非核心執行緒閒置存活時間 | 超過核心數的執行緒閒置多久回收 |
unit | 時間單位 | 配合 keepAliveTime |
workQueue | 任務阻塞佇列 | 核心滿時任務入隊策略,直接影響擴容觸發時機 |
threadFactory | 執行緒建立工廠 | 自訂命名、守護屬性、優先級,便於排查 |
handler | 拒絕策略 | 佇列滿且達最大線程時如何處理新任務 |

| 佇列類型 | 特性 | 適用場景 | 工廠方法預設 |
|---|---|---|---|
SynchronousQueue | 無容量直遞佇列,生產者直接移交消費者 | 任務即時執行、無積壓、需快速擴容 | newCachedThreadPool |
LinkedBlockingQueue | 無界鏈表佇列(預設 Integer.MAX_VALUE) | 任務量大、可接受延遲、核心線程固定處理 | newFixedThreadPool、newSingleThreadExecutor |
ArrayBlockingQueue | 有界陣列佇列,需指定容量 | 資源受限、需防止 OOM、可控擴容 | 自訂 |
DelayedWorkQueue | 延遲任務優先級佇列(堆) | 定時/週期任務 | newScheduledThreadPool |
關鍵洞見:
FixedThreadPool使用無界佇列 →maximumPoolSize永遠不生效,任務積壓可能導致 OOM。
CachedThreadPool使用同步佇列 → 最大線程數Integer.MAX_VALUE,突發流量可能建立過多線程導致 CPU 耗盡。
生產環境強烈建議自訂有界佇列 + 明確拒絕策略,而非直接使用 Executors 預設工廠(阿里巴巴開發手冊強制規範)。
execute(task)。running < corePoolSize → 建立核心執行緒 執行任務。workQueue.offer(task) 入隊成功 → 任務等待調度。running < maximumPoolSize → 建立非核心執行緒 執行任務。handler.rejectedExecution()。執行緒執行完任務後,循環 workQueue.poll(keepAliveTime) 獲取新任務;超時無任務且 running > corePoolSize → 執行緒銷毀。
| 任務類型 | 推薦公式 | 說明 |
|---|---|---|
| CPU 密集型(計算、加密、圖像處理) | N_cpu + 1 | 避免上下文切換開銷,+1 確保偶發缺頁中斷時 CPU 不閒置 |
| I/O 密集型(資料庫、HTTP、檔案讀寫) | 2 * N_cpu 或 N_cpu * (1 + 平均等待時間/平均工作時間) | 線程阻塞時 CPU 可切換執行其他線程,適當超配提升吞吐 |
| 混合型 | 拆分為 CPU/I/O 兩個專用池 | 隔離資源爭用,各自套用對應公式 |
N_cpu = Runtime.getRuntime().availableProcessors()(邏輯核心數,含超執行緒)。
ThreadPoolExecutor 明確指定有界佇列與拒絕策略。order-process-)、非守護執行緒、正常優先級。AbortPolicy(預設,拋異常,關鍵業務)CallerRunsPolicy(呼叫者執行,緩衝壓力,非關鍵批次)DiscardOldestPolicy(捨棄最舊任務,緩存場景)DiscardPolicy(靜默捨棄,日誌/監控可容忍丟失)executor.allowCoreThreadTimeOut(true),應對流量波動釋放資源。shutdown() 停止接受新任務 + awaitTermination(timeout) 等待現有任務完成,避免資料丟失。執行緒池非「配好即忘」,需根據業務負載特徵(CPU/I/O 比例)、流量模式(平穩/突發)、資源限制(記憶體/CPU)科學設定七大參數與佇列。理解 ThreadPoolExecutor 執行流程與佇列交互機制,是排查線上併發問題、調優系統吞吐的關鍵鑰匙。