在 Java 並發編程領域,線程池是提升系統性能、穩定性的核心組件。無論是 JVM 常量池、數據庫連接池,還是各類對象池,其設計哲學殊途同歸——通過複用昂貴資源降低創建銷毀開銷。本文將從原理、源碼、參數配置到自定義實現,全方位剖析線程池的核心機制。
線程池帶來的三大核心收益:
線程池處理任務的決策邏輯可概括為三級判斷:

public void execute(Runnable command) {
if (command == null) throw new NullPointerException();
int c = ctl.get();
// 階段1:核心線程不足,嘗試創建
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) return;
c = ctl.get();
}
// 階段2:入隊工作隊列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 二次檢查:線程池關閉或線程意外死亡時的兜底
if (!isRunning(recheck) && remove(command)) reject(command);
else if (workerCountOf(recheck) == 0) addWorker(null, false);
}
// 階段3:隊列滿,嘗試擴容非核心線程
else if (!addWorker(command, false)) reject(command);
}
addWorker() 將任務封裝為 Worker(實現 Runnable),加入 workers 集合後啟動線程。Worker.run() 循環調用 getTask() 從隊列獲取任務:
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock();
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
try {
beforeExecute(wt, task);
Throwable thrown = null;
task.run();
afterExecute(task, thrown);
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
| 參數 | 含義 | 調優建議 |
|---|---|---|
| corePoolSize | 核心線程數 | CPU 密集型 ≈ CPU 核心數;IO 密集型 ≈ 2×CPU 核心數 |
| maximumPoolSize | 最大線程數 | 配合隊列類型:有界隊列可設大,無界隊列該參數無效 |
| workQueue | 任務隊列 | ArrayBlockingQueue(有界)、LinkedBlockingQueue(無界)、SynchronousQueue(直接提交) |
| ThreadFactory | 線程工廠 | 建議自定義命名前綴,便於排查問題 |
| RejectedExecutionHandler | 拒絕策略 | AbortPolicy(默認拋異常)、CallerRunsPolicy(調用者執行)、DiscardPolicy(丟棄)、DiscardOldestPolicy(丟棄最舊) |
以下簡易實現展示核心機制:阻塞隊列 + 工作線程循環取任務 + 中斷關閉:
public class DemoThreadPool implements ThreadPool {
private BlockingQueue workQueue;
private List workers;
private volatile boolean isShutdown = false;
public DemoThreadPool(int num) {
workQueue = new ArrayBlockingQueue<>(num);
workers = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < num; i++) {
DemoThread dt = new DemoThread(workQueue);
workers.add(dt);
new Thread(dt, "Worker-" + i).start();
}
}
@Override public void execute(Runnable job) {
if (isShutdown) throw new IllegalStateException("Pool shutdown");
try { workQueue.put(job); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
}
@Override public void shutdown() {
isShutdown = true;
workers.forEach(DemoThread::stopToSelf);
}
static class DemoThread implements Runnable {
private final BlockingQueue queue;
private volatile boolean running = true;
DemoThread(BlockingQueue q) { this.queue = q; }
public void run() {
while (running) {
try { queue.take().run(); }
catch (InterruptedException e) { if (!running) break; }
}
}
void stopToSelf() { running = false; Thread.currentThread().interrupt(); }
}
}
線程池是 Java 並發編程的基石,深入理解其原理與參數交互關係,才能在高併發場景下構建穩定、高效的系統。建議結合源碼閱讀、壓測驗證,根據業務特點精細化調優。