ThreadPoolExecutor源码分析
简介
ExecutorService主要使用线程池中的可用线程执行提交的任务,主要用于解决两个不同的问题:执行大量异步任务时改善性能和管理资源。
四种拒绝策略
- ThreadPoolExecutor.AbortPolicy: 丢弃任务,并抛出RejectedExecutionException异常
- ThreadPoolExecutor.CallerRunsPolicy: 通过调用execute方法的线程直接处理被拒绝的任务,除非线程池被shutdown,那么这个任务会被丢弃
- ThreadPoolExecutor.DiscardOldestPolicy: 将最早插入队列且未被处理的任务丢弃,并且重新执行execute方法,除非线程池被shutdown,那么这个任务会被丢弃
- ThreadPoolExecutor.DiscardPolicy: 直接丢弃任务,没有抛任何的异常信息
线程池的状态
- RUNNING (运行状态): 能接受新提交的任务, 并且也能处理阻塞队列中的任务.
- SHUTDOWN (关闭状态): 不再接受新提交的任务, 但却可以继续处理阻塞队列中已保存的任务. 在线程池处于 RUNNING 状态时, 调用 shutdown()方法会使线程池进入到该状态.
- STOP(停止状态) : 不能接受新提交的任务, 也不能处理阻塞队列中已保存的任务, 并且会中断正在处理中的任务.调用 shutdownNow() 方法会使线程池进入到该状态.
- TIDYING (清理状态): 所有的任务都已终止了, workerCount (有效线程数) 为0, 线程池进入该状态后会调用 terminated() 方法以让该线程池进入TERMINATED 状态. 当线程池处于 SHUTDOWN 状态时, 如果此后线程池内没有线程了并且阻塞队列内也没有待执行的任务了 (即: 二者都为空), 线程池就会进入到该状态. 当线程池处于 STOP 状态时, 如果此后线程池内没有线程了, 线程池就会进入到该状态.
- TERMINATED (终止状态): terminated() 方法执行完后就进入该状态.
提交任务
/**
* 在之后的某个时间点执行给定的任务,这个任务会被新创建的线程或线程池中已经存在的线程执行
* 如果任务不能被提交执行,造成这个问题的原因是:线程池被shutdown
* 或线程池中的线程容量达到最大值,任务被具体的拒绝策略处理
* /
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* 1. 有效线程数比核心线程数少,则创建新的线程,并加入到WorkerSet集合中,执行任务
* 2. 有效线程数大于核心线程数,或加入到WorkerSet集合失败,线程池处于RUNNABLE
* 状态,则将当前任务加入到队列中,再次判断线程池的状态
* a. 如果线程池不处于RUNNABLE状态,则移除队列中的该任务,移除成功,使用相应的拒绝策略处理该任务。
* b. 如果线程池中的有效线程数为0, 则创建一个空任务的线程
* 3. 如果第2步中的任务加入队列失败(可能队列满),则通过调用addWorker将任务加入到
* WorkerSet集合中,执行任务。加入失败,则使用相应的拒绝策略处理该任务。
*/
int c = ctl.get();
// 创建新的执行任务线程,并启动任务
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
// 线程池处于RUNNING状态,并且任务加入到workQueue
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//线程池不处于RUNNING状态,移除任务
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//加入队列失败,创建新从线程,并启动执行任务
else if (!addWorker(command, false))
reject(command);
}
/**
* 该方法主要功能为创建一个Worker任务,将Worker加入到Set集合中,并执行提交的任务
* /
private boolean addWorker(Runnable firstTask, boolean core) {
//判断是否有必要创建并启动Worker来执行线程任务
retry:
for (;;) {
//获取ctl值和运行状态
int c = ctl.get();
int rs = runStateOf(c);
// 在以下三种情况下,addWorker失败,线程不会被执行
// 线程池处于 STOP, TYDING 或 TERMINATD状态
// 线程池处于SHUTDOWN状态且firstTask != null
// 线程池处于SHUTDOWN状态且workQueue为空
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
// 线程池的有效线程数大于等于线程池最大容量(理论最大容量为CAPACITY,
//实际最大容量为(core ? corePoolSize : maximumPoolSize)),则直接返回,线程不会被执行
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
// 线程池的有效线程数+1,成功,则退出循环,继续执行其他操作
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
//不成功:判断线程状态是否改变,改变了,则重新开始retry循环,没有改变,则重新设置线程池中的有效线程数
if (runStateOf(c) != rs)
continue retry;
}
}
// 创建Worker任务,并启动执行
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//获取锁之后再次检查,ThreadFactory失败或在获取锁之前shutdown,则退出
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
//worker加入到set容器中
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
// 启动Worker线程
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
/**
* Worker类主要保留线程运行任务的中断状态,使用独占锁
* /
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;
/** Thread this worker is running in. Null if factory fails. */
final Thread thread;
/** Initial task to run. Possibly null. */
Runnable firstTask;
/** Per-thread task counter */
volatile long completedTasks;
/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
// Lock methods
//
// The value 0 represents the unlocked state.
// The value 1 represents the locked state.
protected boolean isHeldExclusively() {
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
/**
* 循环从queue中获取任务,并执行
* /
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
// 循环从queue中获取任务
while (task != null || (task = getTask()) != null) {
w.lock();
// 如果线程池停止了,确保线程被中断了,如果线程池正在运行,确保线程没有被中断
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
//执行任务的run方法
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//执行清理操作
processWorkerExit(w, completedAbruptly);
}
}
/**
* 清理动作
* /
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//统计完成任务的数量
completedTaskCount += w.completedTasks;
//移除Set集合中的完成任务的worker线程
workers.remove(w);
} finally {
mainLock.unlock();
}
// 尝试终止线程池
tryTerminate();
// 线程池未被终止,保留最小线程数
int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
//allowCoreThreadTimeOut : false 表示核心线程即使空闲也保留 true:核心线程等待keepAliveTime超时时间
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}
/**
* 尝试终止线程:
* /
final void tryTerminate() {
for (;;) {
int c = ctl.get();
// 当前线程池的状态为以下几种情况时,直接返回:
// 1. RUNNING,因为还在运行中,不能停止;
// 2. TIDYING或TERMINATED,因为线程池中已经没有正在运行的线程了;
// 3. SHUTDOWN并且等待队列非空,这时要执行完workQueue中的task;
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
// 如果线程数量不为0,则中断一个空闲的工作线程,并返回
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
终止线程池(shutdown)
/**
* 终止线程,终止之前提交的任务会被执行,但是新的任务不会被接收。重复调用不会有任何影响
* 这个方法不会等待先前提交的任务被完全执行,可以使用awaitTermination做这个事
* /
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//安全管理,使调用者有权限终止线程
checkShutdownAccess();
//设置线程池的状态为SHUTDOWN状态
advanceRunState(SHUTDOWN);
//中断空闲Worker任务
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
// 尝试终止线程
tryTerminate();
}
立即终止线程池(shutdownNow)
/**
* 试图停止所有正在执行的任务,暂停正在处理中的任务,返回等待执行的任务列表。这些任务
* 会从queue中移除并被返回。
* 这个方法不会等待正在执行的任务终止。使用awaitTermination来终止。
* /
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//安全管理,使调用者有权限终止线程
checkShutdownAccess();
//设置线程池的状态为STOP状态
advanceRunState(STOP);
//中断正在执行的线程
interruptWorkers();
//清理queue中的任务
tasks = drainQueue();
} finally {
mainLock.unlock();
}
//尝试终止线程
tryTerminate();
return tasks;
}