https://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor
如果能好好阅读官方文档,也就不太需要阅读这篇文章了。。。
按照自己对源码的理解,画了一个图,且看且珍惜。。。
不看懂这些,后续代码也很难看懂吧~
/**
* 主池子的控制状态ctl,是一个原子整数,包含两个含义的字段
* workerCount 表示当前有效的线程数
* runState 表示运行状态,是否正在运行、关闭等
* The main pool control state, ctl, is an atomic integer packing
* two conceptual fields
* workerCount, indicating the effective number of threads
* runState, indicating whether running, shutting down etc
*
* 为了将这两个字段打包进一个int,我们限制workerCount在(2^29)-1而不是(2^31)-1
* 如果这在将来是个问题,可以把变量改成AtomicLong类型,并调整移位和掩码常数
* 但是在需要之前,使用int可以使代码更快以及使用更简单。
* In order to pack them into one int, we limit workerCount to
* (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
* billion) otherwise representable. If this is ever an issue in
* the future, the variable can be changed to be an AtomicLong,
* and the shift/mask constants below adjusted. But until the need
* arises, this code is a bit faster and simpler using an int.
*
* workerCount 是当前已经被允许启动并不允许停止的worker数量
* 该值可能与当前实际存活的线程数量不同,举个例子,当一个ThreadFactory创建一个线程失败了,并且即将退出的线程在终止之前仍然在执行。
* 用户可见的pool size就是当前workers的大小。
* The workerCount is the number of workers that have been
* permitted to start and not permitted to stop. The value may be
* transiently different from the actual number of live threads,
* for example when a ThreadFactory fails to create a thread when
* asked, and when exiting threads are still performing
* bookkeeping before terminating. The user-visible pool size is
* reported as the current size of the workers set.
*
* runState变量提供主要生命周期控制,具有以下值:
* RUNNING: 接受新的任务并且处理正在排队的任务
* SHUTDOWN:不接受新的任务,但是处理正在排队的任务
* STOP:不接受新的任务,不处理正在排队的任务,打断目前正在处理的任务
* TIDYING:所有的任务都已经终止,workerCount为零,线程转换到TIDYING状态,并且即将执行terminated()函数。
* TERMINATED:terminated()函数执行完成。
* The runState provides the main lifecycle control, taking on values:
*
* RUNNING: Accept new tasks and process queued tasks
* SHUTDOWN: Don't accept new tasks, but process queued tasks
* STOP: Don't accept new tasks, don't process queued tasks,
* and interrupt in-progress tasks
* TIDYING: All tasks have terminated, workerCount is zero,
* the thread transitioning to state TIDYING
* will run the terminated() hook method
* TERMINATED: terminated() has completed
*
*
* The numerical order among these values matters, to allow
* ordered comparisons. The runState monotonically increases over
* time, but need not hit each state. The transitions are:
*
* RUNNING -> SHUTDOWN 当调用shutdown()或finalize()函数
* On invocation of shutdown(), perhaps implicitly in finalize()
* (RUNNING or SHUTDOWN) -> STOP 当调用shutdownNow()
* On invocation of shutdownNow()
* SHUTDOWN -> TIDYING 当workers和workQueue都是空的时候
* When both queue and pool are empty
* STOP -> TIDYING 当workers是空的时候
* When pool is empty
* TIDYING -> TERMINATED 当terminated()函数执行完成
* When the terminated() hook method has completed
*
* 当state是TERMINATED的时候,那些在awaitTermination()函数中等待的线程,会立即返回
* Threads waiting in awaitTermination() will return when the
* state reaches TERMINATED.
*
* 检测状态从SHUTDOWN到TIDYING是比较困难的,因为在SHUTDOWN状态时,workQueue可能会在空和非空切换,所以我们只有在workerCount为0时,终止。
* (有时我们需要重复检测state,see below。。。)
* Detecting the transition from SHUTDOWN to TIDYING is less
* straightforward than you'd like because the queue may become
* empty after non-empty and vice versa during SHUTDOWN state, but
* we can only terminate if, after seeing that it is empty, we see
* that workerCount is 0 (which sometimes entails a recheck -- see
* below).
*/
// 以下的操作符合前文说的,将 workerCount 和 runState打包在一个int里
// 高3位表示runState,低29位表示workerCount
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; // 29
private static final int CAPACITY = (1 << COUNT_BITS) - 1; // 2^29 - 1 = 536870911
// runState is stored in the high-order bits
// runState存储在高位
// 最高位代表符号位,1 为负数 0 为正数
private static final int RUNNING = -1 << COUNT_BITS; // 10100000 00000000 00000000 00000000 -2^29 -536870912
private static final int SHUTDOWN = 0 << COUNT_BITS; // 00000000 00000000 00000000 00000000
private static final int STOP = 1 << COUNT_BITS; // 00100000 00000000 00000000 00000000 2^29 536870912
private static final int TIDYING = 2 << COUNT_BITS; // 01000000 00000000 00000000 00000000 2^30 1073741824
private static final int TERMINATED = 3 << COUNT_BITS; // 01100000 00000000 00000000 00000000 2^30+2^29 1610612736
// Packing and unpacking ctl
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; }
public ThreadPoolExecutor(int corePoolSize, /* 指定线程池中核心线程的数量,即使是空闲状态,也存在线程池中,除非设置了allowCoreThreadTimeOut变量 */
int maximumPoolSize, /* 指定线程池中最大线程数量 */
long keepAliveTime, /* 当前线程数量大于核心线程数量时,空闲线程终止等待新任务的最大超时时间 */
TimeUnit unit, /* keepAliveTime 的单位 */
BlockingQueue workQueue, /* 这个队列将保存待执行的任务 */
ThreadFactory threadFactory, /* 用于executor创建线程的工厂 */
RejectedExecutionHandler handler) { /* 当达到了线程池的数量边界,或达到了队列的容量,终止执行的处理handler */
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
* 处理分3步:
*
* 1.如果当前运行的线程数量小于corePoolSize,则尝试用Runnable command作为它的第一个task来启动一个新的线程。
* 调用addWorkder函数,这个函数中会以原子的方式来检查runState和workerCount,它会通过return false来防止那些不应该添加线程时出现的警告。
*(比如workerCount大于CAPACITY 或者 大于 corePoolSize or maximumPoolSize)
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2.如果command能够成功插入workQueue,我们需要进行二次检查来判断是否我们需要添加一个新的线程
* (因为上次检查之后,之前的工作线程已经died,或者线程池的状态改变了)
* 所以我们需要重新检测runState,如果线程池停止了,我们会remove之前的commnad 并且 拒绝这个command;如果当前workerCount为0,我们会启动一个新的线程
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3.如果我们插入command不成功,我们会尝试启动一个新的线程。
* 如果失败了,我们知道线程池已经shut down或者已经达到饱和状态了,所以我们拒绝这个command。
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) // 尝试创建核心线程,处理command
return;
c = ctl.get();
}
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); // Runnable为null时,runWorker方法会调用getTask,尝试从workQueue获取Runnable
}
else if (!addWorker(command, false)) // 尝试创建非核心线程,处理command
reject(command);
}
addWorker函数,可以结合execute函数一起看,主要作用就是一系列的判断,初始化worker,调用worker run。
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
// 这里负责校验runState以及workQueue,从而决定是否需要拒绝command
// SHUTDOWN状态是不接受新任务,但是会处理排队任务
// rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty() 表达式用于判断是否当前处于SHUTDOWN状态 并且 是否为处理排队任务
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false; // 这里比较容易理解,wc大于等于容量,或者大于等于边界coreSize或maxSize,则拒绝command
if (compareAndIncrementWorkerCount(c))
break retry; // CAS操作成功,则break retry代码段。
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs) // 重新校验状态,如果状态变化了,重新直接retry,否则重新执行内层for循环,继续CAS
continue 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); // new Worker
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock(); // 尝试获取锁,当前使用的是NonfairSync
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
// 在获取锁之后,需要重新检查
// 如果在获得锁之前,runState 变化了,或者线程工厂失败了,需要退出
int rs = runStateOf(ctl.get());
// 所有状态都OK,处理成员变量和标志位逻辑
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start(); // 运行线程,最终调用runWorker
workerStarted = true;
}
}
} finally {
// 如果添加不成功,则调用addWorkerFailed
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
核心函数 -- 由worker类的run()函数调用
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true; // 标志worker是否异常结束
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// 以下判断是否需要interrupt worker
// 判断线程池状态
// 再次判断线程和线程池状态,因可能调用了shutdownnow
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
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 Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
// 线程池状态(状态参照前文),减少worker数量
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// 核心线程在getTask永驻,始终等待task
// 非核心线程,在这里返回null之后,结束
// allowCoreThreadTimeOut 如果为true,则核心线程也会timeout,结束
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
// 减少worker数量,并返回null
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
// poll等待keepAliveTime,或直接take
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : // 等待keepAliveTime
workQueue.take();
// 获取到runnable则返回,否则设置timeOut为true
if (r != null)
return r;
timedOut = true; // time out
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// 如果是异常结束的,则减少worker数量,正常结束会在getTask函数中做CAS
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
// 统计总计完成的task数量
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
// 判断线程池状态,是否需要中断worker,以及结束线程池
tryTerminate();
// 若当前线程池的状态是RUNNING或SHUTDOWN时,
// 至少保证线程池里有1个或者corePoolSize个线程存在。
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
}
addWorker(null, false);
}
}
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) {
}
}
}
}