頻繁創建銷毀線程開銷大,線程池實現線程復用,java.util.concurrent.Executors 提供工廠方法,ThreadPoolExecutor 為核心實現。本文系統剖析其參數、隊列、拒絕策略、自定義與擴展機制。
ExecutorService executor = Executors.newFixedThreadPool(5); // 固定 5 線程
for (int i = 0; i < 10; i++) {
final int no = i;
executor.execute(() -> {
System.out.println("into" + no);
Thread.sleep(1000);
System.out.println("end" + no);
});
}
executor.shutdown(); // 禁止新任務,等待執行完畢
運行結果顯示任意時刻最多 5 線程並發,體現線程復用。
| 方法 | 特點 | 適用場景 |
|---|---|---|
newFixedThreadPool(n) | 核心=最大=n,無界隊列 | 長期任務,控制並發度 |
newCachedThreadPool() | 核心 0,最大 Integer.MAX_VALUE,60s 空閒回收,同步隊列 | 大量短期異步任務 |
newSingleThreadExecutor() | 單線程串行,無界隊列 | 順序執行任務 |
newScheduledThreadPool(n) | 支持定時/周期任務 | 定時調度 |
public ThreadPoolExecutor(
int corePoolSize, // 核心線程數
int maximumPoolSize, // 最大線程數
long keepAliveTime, // 非核心線程空閒存活時間
TimeUnit unit, // 時間單位
BlockingQueue<Runnable> workQueue, // 任務隊列
ThreadFactory threadFactory, // 線程工廠
RejectedExecutionHandler handler // 拒絕策略
)
workQueue。handler 處理拒絕。keepAliveTime → 回收。ArrayBlockingQueue:有界數組隊列,FIFO,固定大小。LinkedBlockingQueue:無界鏈表隊列(默認),FIFO,FixedThreadPool 默認使用。SynchronousQueue:零容量直接遞交隊列,CachedThreadPool 默認使用,生產者等待消費者。PriorityBlockingQueue:優先級隊列,任務需實現 Comparable。SynchronousQueue<String> sq = new SynchronousQueue<>();
Semaphore sem = new Semaphore(1); // 互斥鎖
// 10 消費者
for (int i=0;i<10;i++) new Thread(() -> {
sem.acquire();
String input = sq.take(); // 阻塞等待
System.out.println(Thread.currentThread().getName() + ":" + TestDo.doSome(input));
sem.release();
}).start();
// 10 生產者
for (int i=0;i<10;i++) sq.put(i + "");
輸出嚴格串行,前一任務結束後下一任務開始。
| 策略 | 行為 | 適用場景 |
|---|---|---|
AbortPolicy | 拋出 RejectedExecutionException | 關鍵業務,不可丟失,需立即發現 |
CallerRunsPolicy | 調用者線程直接執行任務 | 緩衝峰值,利用調用者資源 |
DiscardPolicy | 默默丟棄任務 | 非關鍵、可容忍丟失 |
DiscardOldestPolicy | 丟棄隊列頭部最老任務,重試提交 | 優先處理新任務 |