線程池是一種多線程處理模式:任務加入隊列,由預先創建的工作線程自動取出執行。核心優勢在於降低線程創建/銷毀開銷,特別適合任務耗時短、數量大的高併發場景(如 Web 伺服器)。
單次任務處理時間 = T1(創建線程) + T2(執行任務) + T3(銷毀線程)。
若 T1+T3 遠大於 T2,引入線程池可將 T1、T3 移至啟動/空閒時期,顯著提升吞吐量。
例:每日 50,000 請求,無池化需創建 50,000 線程;池化僅需固定數量(如 100),大幅降低記憶體壓力與 GC 負擔。
import java.util.*;
import org.apache.log4j.Logger;
public final class ThreadPool {
private static final Logger logger = Logger.getLogger(ThreadPool.class);
private static final Logger taskLogger = Logger.getLogger("TaskLogger");
private static final boolean DEBUG = taskLogger.isDebugEnabled();
private static ThreadPool instance;
public static final int SYSTEM_BUSY_TASK_COUNT = 150;
public static int workerNum = 5;
private static int taskCounter = 0;
public static boolean systemIsBusy = false;
private final List taskQueue = Collections.synchronizedList(new LinkedList<>());
public PoolWorker[] workers;
private ThreadPool() { this(workerNum); }
private ThreadPool(int n) {
workerNum = n;
workers = new PoolWorker[n];
for (int i = 0; i < n; i++) workers[i] = new PoolWorker(i);
}
public static synchronized ThreadPool getInstance() {
if (instance == null) instance = new ThreadPool();
return instance;
}
public void addTask(Task newTask) {
synchronized (taskQueue) {
newTask.setTaskId(++taskCounter);
newTask.setSubmitTime(new Date());
taskQueue.add(newTask);
taskQueue.notifyAll();
}
logger.info("Submit Task<" + newTask.getTaskId() + ">: " + newTask.info());
}
public void batchAddTask(Task[] tasks) {
if (tasks == null || tasks.length == 0) return;
synchronized (taskQueue) {
for (Task t : tasks) if (t != null) {
t.setTaskId(++taskCounter);
t.setSubmitTime(new Date());
taskQueue.add(t);
}
taskQueue.notifyAll();
}
for (Task t : tasks) if (t != null) logger.info("Submit Task<" + t.getTaskId() + ">: " + t.info());
}
public String getInfo() {
StringBuilder sb = new StringBuilder();
sb.append("\nTask Queue Size: ").append(taskQueue.size());
for (int i = 0; i < workers.length; i++)
sb.append("\nWorker ").append(i).append(" is ").append(workers[i].isWaiting() ? "Waiting." : "Running.");
return sb.toString();
}
public synchronized void destroy() {
for (PoolWorker w : workers) { w.stopWorker(); w = null; }
taskQueue.clear();
}
private class PoolWorker extends Thread {
private final int index;
private boolean isRunning = true;
private boolean isWaiting = true;
PoolWorker(int index) { this.index = index; start(); }
void stopWorker() { isRunning = false; }
boolean isWaiting() { return isWaiting; }
@Override
public void run() {
while (isRunning) {
Task r = null;
synchronized (taskQueue) {
while (taskQueue.isEmpty()) {
try { taskQueue.wait(20); }
catch (InterruptedException e) { logger.error(e); }
}
r = taskQueue.remove(0);
}
if (r != null) {
isWaiting = false;
try {
if (DEBUG) {
r.setBeginExecuteTime(new Date());
taskLogger.debug("Worker<" + index + "> start Task<" + r.getTaskId() + ">");
}
if (r.needExecuteImmediate()) new Thread(r).start();
else r.run();
if (DEBUG) {
r.setFinishTime(new Date());
taskLogger.debug("Worker<" + index + "> finish Task<" + r.getTaskId() + ">");
}
} catch (Exception e) { e.printStackTrace(); logger.error(e); }
isWaiting = true;
}
}
}
}
}
public abstract class Task implements Runnable {
private Date generateTime, submitTime, beginExecuteTime, finishTime;
private long taskId;
public Task() { this.generateTime = new Date(); }
@Override public void run() {
// 範本:beginTransaction(); Task[] subtasks = taskCore(); commitTransaction(); batchAddTask(subtasks);
}
public abstract Task[] taskCore() throws Exception;
protected abstract boolean useDb();
protected abstract boolean needExecuteImmediate();
public abstract String info();
// Getter/Setter 略...
}
wait/notifyAll 機制高效等待任務,避免忙等待。needExecuteImmediate)與批量提交。