
execute(Runnable),非線程池,僅執行工具ExecutorService cached = Executors.newCachedThreadPool();
特性:
Integer.MAX_VALUESynchronousQueue 直接移交)風險:無上限,任務提交速度 > 處理速度時會瘋狂建立線程 → OOM。生產環境慎用或包裝限制。
// 測試:5個任務間隔1秒,觀察線程重用
cached.execute(() -> System.out.println(Thread.currentThread().getName()));
// 輸出:pool-1-thread-1 (重用同一線程)
ExecutorService fixed = Executors.newFixedThreadPool(3);
特性:
LinkedBlockingQueue 無界隊列風險:無界隊列積壓大量任務 → 記憶體飆升。提交速度持續 > 處理速度時同樣危險。
// 測試:5個任務,每個睡2秒,固定3線程
// 輸出前3個立即執行,2秒後執行後2個
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(3);
特性:支援延遲執行、固定頻率、固定延遲三種模式。
// 延遲 3 秒執行一次
scheduled.schedule(() -> System.out.println("延遲3秒"), 3, TimeUnit.SECONDS);
// 延遲 1 秒後,每 3 秒執行一次(固定頻率)
scheduled.scheduleAtFixedRate(() -> System.out.println("週期執行"), 1, 3, TimeUnit.SECONDS);
// 延遲 1 秒後,每次執行結束 3 秒後再執行(固定延遲)
scheduled.scheduleWithFixedDelay(() -> System.out.println("固定延遲"), 1, 3, TimeUnit.SECONDS);
區別:scheduleAtFixedRate 以**開始時間**為基準,執行時間長可能導致重疊;scheduleWithFixedDelay 以**結束時間**為基準,無重疊風險。
ExecutorService single = Executors.newSingleThreadExecutor();
特性:
優於 newFixedThreadPool(1):不可重新配置為多線程,語義更清晰、防誤用。
new ThreadPoolExecutor(
corePoolSize, // 核心線程數(常駐)
maximumPoolSize, // 最大線程數
keepAliveTime, // 非核心線程空閒存活時間
unit, // 時間單位
workQueue, // 任務隊列(關鍵!)
threadFactory, // 線程工廠(命名、優先級、守護線程)
handler // 拒絕策略(隊列滿 + 線程達最大時)
);
| 隊列類型 | 特性 | 適用場景 | 典型搭配 |
|---|---|---|---|
SynchronousQueue |
無容量,直接移交 | 任務輕量、追求高吞吐 | CachedThreadPool |
LinkedBlockingQueue |
無界(預設 Integer.MAX_VALUE) | 任務耗時、需緩衝 | FixedThreadPool、SingleThreadExecutor |
ArrayBlockingQueue |
有界陣列 | 需嚴格控制記憶體、支援背壓 | 自訂生產級線程池 |
PriorityBlockingQueue |
優先級排序 | 任務有優先級區分 | 業務優先級調度 |
AbortPolicy(預設):拋 RejectedExecutionExceptionCallerRunsPolicy:呼叫者執行緒執行任務(自然背壓)DiscardPolicy:靜默丟棄新任務DiscardOldestPolicy:丟棄隊列最舊任務,嘗試重新提交@Configuration
public class ThreadPoolConfig {
@Bean("businessExecutor")
public ThreadPoolExecutor businessExecutor() {
return new ThreadPoolExecutor(
10, // 核心:CPU 核心數 * (1 + 平均等待/計算比)
20, // 最大:核心 * 2 或根據壓測調整
60, TimeUnit.SECONDS, // 存活時間
new ArrayBlockingQueue<>(500), // 有界隊列:防 OOM
new CustomThreadFactory("biz-"), // 可見命名:biz-1, biz-2...
new ThreadPoolExecutor.CallerRunsPolicy() // 背壓:呼叫者執行
);
}
// 优雅關閉
@PreDestroy
public void shutdown() {
businessExecutor().shutdown();
try {
if (!businessExecutor().awaitTermination(30, TimeUnit.SECONDS)) {
businessExecutor().shutdownNow();
}
} catch (InterruptedException e) {
businessExecutor().shutdownNow();
}
}
}
corePoolSize = CPU 核心數 + 1corePoolSize = CPU 核心數 * (1 + 平均等待時間 / 平均工作時間)| 指標 | 健康閾值 | 異常信號 |
|---|---|---|
| activeCount | < corePoolSize * 0.8 | 持續接近 maximumPoolSize |
| queue.size() | < capacity * 0.5 | 持續增長、接近上限 |
| completedTaskCount | 穩定增長 | 停滯或極慢 |
| rejectedExecutionCount | 0 | > 0 即需擴容或優化 |
| 場景 | 推薦方案 | 避坑提醒 |
|---|---|---|
| 短任務、量大、併發不可預測 | 自訂 ThreadPoolExecutor + 有界隊列 + CallerRunsPolicy |
禁用 newCachedThreadPool |
| 固定併發度、長任務 | newFixedThreadPool 或自訂固定核心池 |
注意無界隊列風險 |
| 定時/週期任務 | newScheduledThreadPool 或 Spring @Scheduled |
單線程調度器任務堵塞會延遲後續任務 |
| 嚴格序列化處理 | newSingleThreadExecutor |
避免在單線程中執行耗時阻塞操作 |
| 高可用、需監控、動態調整 | 整合 DynamicThreadPool (美團/滴滴開源) |
配置中心動態修改核心參數 |
**核心原則**:**顯式配置優於隱式預設**,**有界隊列優於無界**,**監控告警優於事後排查**。線程池是系統穩定性的基石,投入精力精心設計配置,回報率極高。