ThreadPoolExecutor中有一个非常重要的变量ctl
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
ctl存储了两个概念上的参数:workCount和runState。
高3位存储运行状态runState
低29位表示表示线程数量workCount
Executor存在以下运行状态:RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATED
RUNNING:接收新的task,处理队列中的task
SHUTDOWN:不接收新的task,继续处理队列中的task
STOP:不接收新的task,不再处理队列中的task,中断正在处理的task
TIDYING:所有的task都终止了,线程数量为0,TIDYING状态将调用terminate()钩子方法
TERMINATED:terminate()方法完成
首先看最重要的execute方法
public void execute(Runnable command) {
...
int c = ctl.get();
// 线程数量小于corePoolSize,创建核心线程
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) { // task入队列
int recheck = ctl.get();
//不是RUNNING状态,移除task
if (! isRunning(recheck) && remove(command))
reject(command);
//如果在运行阶段,但是Worker数量为0,创建一个线程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 线程数量小于maximumPoolSize,创建非核心线程
else if (!addWorker(command, false))
reject(command);
}
task入队列后,重新检查运行状态,如果不是RUNNING状态,会移除task
如果是RUNNING状态,检查线程数,如果线程数为0(Executor没有常驻线程),创建一个线程。
addWorker第一个参数为null是正常的,后面说到。
addWorker方法负责创建一个新的线程
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// CODE1
// SHUTDOWN 状态还可以添加线程处理队列的task
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null && // 添加线程而不是添加task
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
// 是否为核心线程
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry; // 跳出retry
c = ctl.get();
if (runStateOf(c) != rs) // State已经发生变化
continue retry; // 重新retry
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask); // 创建Worker
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) {
t.start(); // 启动线程
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
retry有两个循环,外循环是用于重复检查状态,内循环是为了保证compareAndIncrementWorkerCount(c)
CAS成功。
SHUTDOWN状态时,Executor不接收新的task,但还要处理队列中的task,所以还是可以添加线程。
firstTask为null,表示添加新的线程。这就是CODE1的第二个判断条件。
Worker实现了Runnable,run方法调用runWorker
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) { // getTask() == null,该线程退出
w.lock(); // 防止shutdown时终结正在运行的worker
// CODE2
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
...忽略异常处理
// 运行task
task.run();
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
// exit处理
processWorkerExit(w, completedAbruptly);
}
}
CODE2处,如果Executor为STOP状态,中断线程,否则,清除线程中断标识。
- 满足条件state >= STOP&&!wt.isInterrupted(),中断线程
- 调用Thread.interrupted,返回并清除中断标识,
如果返回已中断标识,重新检查state, 如果state >= STOP(这时候!wt.isInterrupted()肯定满足,因为中断标识已清除),中断线程,否则不处理(这是中断标识已清除)。
firstTask为null时,会继续调用getTask,获取队列中的task处理,所以firstTask为null的Worker实际上用于添加线程而不是task。
getTask会获取一个待处理的任务
private Runnable getTask() {
boolean timedOut = false; // 是否已等待超时
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// 检查状态
// rs >= STOP || (rs == SHUTDOWN && workQueue.isEmpty())
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount(); // 减少WorkerCount
return null; // 返回null将结束线程
}
int wc = workerCountOf(c);
// 是否超时等待
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// 两个条件
// 1. wc > maximumPoolSize(不正常情况) 或者等待超时
// 2. wc > 1 || workQueue.isEmpty(),也就是说只有一个线程而且workQueue不是空的,不可以结束线程
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c)) // 减少WorkerCount
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true; // 超出了keepAliveTime
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
allowCoreThreadTimeOut 允许核心线程超时退出。
看看shutdown方法
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 检查shutdown权限
checkShutdownAccess();
// 设置状态为SHUTDOWN
advanceRunState(SHUTDOWN);
// 中断空闲线程
interruptIdleWorkers();
// 调用预留方法
onShutdown();
} finally {
mainLock.unlock();
}
// Terminate
tryTerminate();
}
shutdown方法进入SHUTDOWN状态。
shutdownNow与shutdown类型,只是它不是中断空闲线程,而是中断所有线程,并且进入stop状态
public List shutdownNow() {
List tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}
看看tryTerminate,该方法在所有task都终止,所有线程都退出后,依次进入TIDYING,TERMINATED状态。
final void tryTerminate() {
for (;;) {
int c = ctl.get();
// 检查状态
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty())) // 检查workQueue
return;
// 检查workerCount
if (workerCountOf(c) != 0) {
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 设置状态为TIDYING
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
// 调用terminated方法
terminated();
} finally {
// 设置状态为TERMINATED
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
for循环保证ctl.compareAndSet(c, ctlOf(TIDYING, 0))
操作成功。
如果workerCount不为0,会中断一个空闲线程。
shutdown/shutdownNow都不是立刻进入Terminate状态。
那么什么时候进入Terminate,在processWorkerExit。
completedAbruptly表示异常退出,runWorker方法中的beforeExecute如果抛出异常,completedAbruptly为true
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // 正常情况下,getTask返回null时会decrementWorkerCount
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) { // 正常退出
// 最小线程数
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
// 异常退出或者workerCount小于最小线程数,需要添加线程
addWorker(null, false);
}
}
当所有Worker都processWorkerExit了,就可以进入Terminate了。
submit
submit会返回一个Future对象,这里看一个Future是怎样生成的
public Future> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
主要是创建一个FutureTask。
FutureTask后面再解析。