1 Executor
它用於執行指定的任務,把任務提交與任務執行分離,程序員不需要關注線程的管理,以及任務的執行。
ExecutorService 接口對 Executor 接口提供更多的擴展,ThreadPoolExecutor 類提供
可以擴展的線程池實現,而 Executors 只是對這些 Executor 提供方便的工廠方法。
1.1 類圖
2 Future
2.1 類圖
2.2 FutureTask
類結構:
class FutureTask {
// 任務運行狀態
/*
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
// 底層運行的 callable
private Callable<V> callable;
// 任務結果,非 volatile,因爲受 state 讀寫保護
private Object outcome;
// 運行 callable 任務的線程
private volatile Thread runner;
private volatile WaitNode waiters;
// 在 Treiber stack 中記錄等待中的線程
static final class WaitNode {
volatile Thread thread;
volatile WaitNode next;
WaitNode() { thread = Thread.currentThread(); }
}
}
兩個重要的構造函數:
// 包裝 Callable,state = NEW
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW;
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
第二個構造器使用了 Executors 工具類的 callable() 方法來把 Runnable 適配成 Callable。典型的
適配器模式。
public static <T> Callable<T> callable(Runnable task, T result) {
return new RunnableAdapter<T>(task, result);
}
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
3 ThreadPoolExecutor
3.1 類結構
class ThreadPoolExecutor {
// 狀態控制,包含兩個信息:
// workerCount: 工作線程數
// runState: 表明線程池運行狀態
// RUNNING: 可以接受新的 task,且能處理隊列中的 task
// SHUTDOWN: 不接受新的 task,但能處理隊列中的 task
// STOP: 不接受新的 task,不處理隊列中的 task,並且中斷運行中的 task
// TIDYING: 所有任務都被終止,workerCount = 0,線程狀態爲 TIDYING
// TERMINATED: terminated() 方法執行完成
// RUNNING
// shutdownNow()| \ shutdown()
// |/ \/
// STOP---- SHUTDOWN
// 線程池爲空| / 隊列和線程池都爲空
// |/ \/ \
// TIDYING------------- TERMINATED
// terminated()
// 初始化:ctl = RUNNING
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// 11101
private static final int COUNT_BITS = Integer.SIZE - 3;
// 00011111111111111111111111111111 536870911
// worker 線程最大數量
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState 存儲在高位
// 111 開頭 -536870912
private static final int RUNNING = -1 << COUNT_BITS;
// 000 開頭 0
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 001 開頭 536870912
private static final int STOP = 1 << COUNT_BITS;
// 010 開頭 1073741824
private static final int TIDYING = 2 << COUNT_BITS;
// 011 開頭 1610612736
private static final int TERMINATED = 3 << COUNT_BITS;
// ~CAPACITY = 11100000000000000000000000000000
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
private static boolean isRunning(int c) {
return c < SHUTDOWN;
}
}
3.2 內部類 Worker
private final class Worker extends AbstractQueuedSynchronizer
implements Runnable {
// 執行任務線程
final Thread thread;
// 待執行任務
Runnable firstTask;
// 每個線程完成任務數
volatile long completedTasks;
Worker(Runnable firstTask) {
setState(-1); // 設置AQS的同步狀態爲-1,禁止中斷,直到調用 runWorker
this.firstTask = firstTask;
// 使用 ThreadFactory 創建線程
this.thread = getThreadFactory().newThread(this);
}
/** Delegates main run loop to outer runWorker */
public void run() {
// 核心
runWorker(this);
}
}
3.3 任務執行(execute)
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
// 初始時,ctl = RUNNING = 11100000000000000000000000000000
int c = ctl.get();
// wokerCountOf(c) => c & 00011111111111111111111111111111
// 線程數小於 corePoolSize,創建線程執行 task
if (workerCountOf(c) < corePoolSize) {
// 創建線程,並啓動線程執行 command
if (addWorker(command, true))
return;
c = ctl.get();
}
// 兩種情況:
// ① 線程數大於等於 corePoolSize;
// ② 線程數小於 corePoolSize,但是 addWorker() 線程池狀態不符合條件,或創建線程失敗或啓動線程失敗
// 線程池處於運行狀態才能往隊列添加任務
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);
}
// 線程池非 RUNNING 狀態
// 隊列已滿
// 此時使用 maximumPoolSize 作爲界限判斷
else if (!addWorker(command, false))
reject(command);
}
/**
* addWoker() 方法返回 false 幾種情況:
* 1)線程池停止或 shutdown
* 2)ThreadFactory 創建線程失敗
* @param core true:使用 corePoolSize 作爲界限;false:使用 maximumPoolSize 作爲界限
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// ① 線程池狀態是 RUNNING,可以創建工作線程,即執行下面的 for 循環
// ② 線程池狀態是 STOP、TIDYING 或 TERMINATED,直接返回 false,即不能創建工作線程執行任務
// ③ 線程池狀態時 SHUTDOWN,此時 firstTask 在此種狀態下應該爲 null,即它不能接收新的任務
// 所以如果 firstTask 不爲 null,那麼可以直接返回 false
// 如果 firstTask 爲 null,此時線程池可以處理隊列中任務,所以如果隊列爲空,那麼直接返回 false,否則需要創建工作線程處理隊列中的任務
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
// runState 爲 RUNNING 或 SHUTDOWN
for (;;) {
int wc = workerCountOf(c);
// woker 線程數超過界限,返回 false
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
// CAS 增加 workerCount
if (compareAndIncrementWorkerCount(c))
break retry; // 失敗
c = ctl.get(); // Re-read ctl
// 可能 runState 被其他線程改變,非 RUNNING 或 SHUTDOWN 狀態
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 初始化 Worker,創建線程
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) { // 線程創建成功
// 全局鎖
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 再次檢查線程池的運行狀態等
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive())
// 線程處於活躍狀態,即線程已經開始執行或者還未死亡,正確的應線程在這裏應該是還未開始執行的
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
// 實際會調用 Worker 類的 run() 方法
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted) //未能成功創建執行工作線程
addWorkerFailed(w); //在啓動工作線程失敗後,將工作線程從集合中移除
}
return workerStarted;
}
從上述代碼分析可以看出,有很多書上在分析線程池的執行原理是有問題的。
小結上述邏輯:
- 線程池控制標識是原子類型,即 AtomicInteger
- execute() 方法只關注線程池核心工作流程,具體執行細節交由其他方法處理,主要是 addWorker() 方法
- 工作線程小於 corePoolSize 時,創建工作線程以及執行任務統一交給 addWorker() 方法處理
- addWorker() 方法在創建工作線程執行任務之前,需要判斷線程池當前狀態是否滿足可以創建工作線程。
- RUNNING 狀態可以接收新的任務(能創建工作線程),且能處理隊列中的任務
- SHUTDOWN 狀態不能接收新的任務(不能創建工作線程),但能處理隊列中的任務
- 使用 CAS 計數工作線程,即更新線程池控制標識
- 任務和線程統一由其內部類 Worker 進行封裝,Worker 類本身也是 Runnable
整個流程圖如下,畫的不太好,主要還是爲了梳理邏輯,因爲整個代碼用到了太多 if() 語句的短路思維,當然這些主要是跟線程池的狀態有關。