一. 构造参数和属性含义
corePoolSize
: 池子中保持的线程数量, 即使空闲, 也不会销毁
maximumPoolSize
: 池子中最大的线程数
keepAliveTime
: 当池子中线程数量大于 corePoolSize 时, 哪些空闲的线程多久会 timeout 被销毁
workQueue
: 待执行的任务池
RejectedExecutionHandler
拒绝策略: 默认 AbortPolicy, 直接抛出异常
// 全局的 worker 列表
private final HashSet<Worker> workers = new HashSet<Worker>();
// 控制线程池全局动作的一把主锁. 将线程池 shutdown , 增加 worker , intrupt worker这些操作同步, 避免操作混乱
private final ReentrantLock mainLock = new ReentrantLock();
// 构造方法中传入的工作队列
private final BlockingQueue<Runnable> workQueue;
二. ctl 变量
ctl 一个变量同时记录线程池状态和 RUNNING TASK 的数量.
如下可见线程池有5个状态 (RUNNING … TERMINATED), 所以需要3个比特位记录状态. jdk选择 int 值的高3位记录线程池状态, 低29位记录 RUNNING TASK 的数量. 所以:
* COUNT_BITS
= 29
* CAPACITY
高3位全0, 低29位全1
// 记录 runningState 和 workCount 的变量. 初始化为 RUNNING 态
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; // 32 - 3 = 29
private static final int CAPACITY = (1 << COUNT_BITS) - 1; // 00011111111111111111111111111111
// 高3位记录的 RUNNING STATE
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
// 取高3位
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 取低29位
private static int workerCountOf(int c) { return c & CAPACITY; }
// ctl = "或"操作起到高3位记录 running state, 低29位记录 worker count
private static int ctlOf(int rs, int wc) { return rs | wc; }
三. 线程池中创建线程的方法
线程池中的创建线程
这个动作, 由 Executors 的静态内部类 DefaultThreadFactory 创建的
static class DefaultThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
四. execute() 的执行分三步
线程池执行任务的三个分支:
public void execute(Runnable command) {
int c = ctl.get();
// 分支1 - 新创建线程:
// 如果池子中有少于 corePoolSize 的线程在执行, start 一个新线程, 这个任务当做线程的第一个任务.
// addWorker() 内部会原子性的检查 runState 和 workerCount 2个变量, 不该创建新线程时该调用返回 false
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
// 分支2 - worker 数量已经达到 corePoolSize), 将任务放入全局队列
// 后面会判断, 如果是在线程池 shutDown 后向队列添加 runnable, 会执行拒绝策略
if (isRunning(c) && workQueue.offer(command)) {
// 如果一个 task 可以成功的加入队列, 仍需要 double check 是否需要增加一个线程
// (因为可能在上次检查后, 有线程死掉了或线程池已经被 shutdown)
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 分支3: 如果 task 不能成功加入队列, 则可能是线程池已经 shutdown, 或者已经饱和该执行决绝策略了
else if (!addWorker(command, false))
reject(command);
}
addWorker()
内部还会校验线程数量, 是否需要新建
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c); // running state
int c = ctl.get();
int rs = runStateOf(c);
// (1) 不加锁的情况下, 校验线程池状态的代码.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c); // worker 数量
if (wc >= CAPACITY || // worker 数量太大, 低29位要溢出
wc >= (core ? corePoolSize : maximumPoolSize)) // core: true/false, 决定 wc 是和 coreSize 还是和 maxSize 比较
return false;
// compareAndIncrementWorkerCount(c): CAS递增 ctl 变量, 方法内执行 ctl.compareAndSet(expect, expect + 1);
if (compareAndIncrementWorkerCount(c))
break retry; // CAS 递增成功跳出最外层 retry 循环
c = ctl.get(); // 重读 ctl
if (runStateOf(c) != rs) // 重读 ctl 后发现线程池状态改变, 要从判断状态开始重新循环
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
// (2) 开始在锁下执行创建线程 (Worker)
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// Worker 内部2个属性: thread 和 firstTask
// new Worker() 会从 DefaultThreadFactory 创建新线程
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock; // 线程池主锁
mainLock.lock();
try {
// 在加锁的情况下再次检查, 防止锁获取前线程池 shutdown
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive())
// 新创建的线程还没使用不能是 alive 状态, 如果是,
// 证明 ThreadFactory 中返回的线程正在使用, 是无效的
throw new IllegalThreadStateException();
workers.add(w); // hashSet 中加入 worker
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock(); // 新建成功后就释放锁
}
if (workerAdded) {
t.start(); // 执行新创建的线程中的 Runnable
workerStarted = true;
}
}
} finally {
if (! workerStarted)
// 主要是从全局的 works 中删除新创建的 worker, 并更改一些状态
// 修改 ctl, 减少1个 workerCount
addWorkerFailed(w);
}
return workerStarted;
}
}
- 削减 workerCount
死循环下 CAS 修改 worker 数量
private void decrementWorkerCount() {
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
}
- 操作的锁粒度, 由不加锁, 逐步到加锁的递进完成
(1) 状态检查, 线程数量比较现在不加锁的状态下进行
(2) 当初步判断符合某一个分支后, 先用 CAS 修改 ctl, 像低29位的 worker 数量等. 如果第一步检查失效, CAS 会操作失败
(3) 真正执行增删节点的操作, 在加 mainLock 的情况下进行. 这把锁内部还会重新检查状态, 防止前两部检查遗漏
五. Worker 类的分析
// 继承 AQS 为了自动包含锁, 和被 interupt 的作用
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable{
final Thread thread;
Runnable firstTask; // Initial task to run. Possibly null
volatile long completedTasks; // Per-thread task counter
/** 构造方法 */
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); // thread 属性也持有 Worker Runnable
}
/** 执行 thread.start() 会调用该 Worker.run() 方法 */
public void run() {
runWorker(this); // 见下面分析
}
Worker 和 内部 thread 是互相持有对方为属性的关系:
- (1) worker 持有 thread 作为属性
- (2) thread 持有 worker 作为属性. thread.start() 会执行内部 Runnable 的 run, 就是 Worker 对象的 run().
Worker 对象一旦在线程的addWorker()
方法中创建, 会被立刻开启内部的线程, 从而调用worker#run()
, 即内部的runWorker
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts 的地方. 也是 worker 继承 AQS 的原因
boolean completedAbruptly = true;
try {
// getTask(): 从队列取任务.
while (task != null || (task = getTask()) != null) {
w.lock(); // worker 正在被访问, 不允许其它方法执行了
// 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()) // 响应 interrupt
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
// 提到线程池的 runbale 对象的 run(),
// 如果正常执行, 会跳回 while, 继续从全局队列中取任务
task.run();
}
// 底下这些报错, 都会 throw, 导致内部执行线程结束
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 {
// 任务执行出错会跳到这里.
// 如果不足 corePoolSize, 会创建新的 worker, 代替失败的 worker
processWorkerExit(w, completedAbruptly);
}
}
什么时候将非核心线程删除,让线程个数降低到 corePoolSize
首先明确,只有在有界队列已满后,线程池才会创建新的非核心线程,让线程数量超过 corePoolSize
,小于等于maxPoolSize
。该新建的非核心线程线程的runWorker()
启动后立刻拿任务导致有界队列有空闲位置,从而可以提交新任务。如果线程池设置了超时时间,非核心线程在空闲一段时间后会自行销毁,这是怎么做到的呢?
答案:上文看到,runWorker()
中调用 getTask()
获取任务,
- 如果设置了超时时间
getTask()
会调用带超时时间的workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)
方法从阻塞队列中获取任务,超时返回 null runWorker()
对于 null 任务会执行processWorkerExit()
将 worker 对象从列表中删除
// ThreadPoolExecutor.java
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// 如果触发了 shutown, getTask() 返回null
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
// 判断 worker 是否要被选择宰杀(客户端选择可以宰杀核心线程,或线程池中的线程数量大于核心线程数)
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
/** [关键处]:判断超时后,本方法返回 null,
* runWorker 会在调用处执行 processWorkerExit() 将 worker 从 worker列表中删除
*/
if ((wc > maximumPoolSize // (1) worker 数量大于 maxPoolSize
|| (timed && timedOut)) // (2) timed: 需要被宰杀,timedOut: 且已经超时
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
// 如果设置了超时时间,阻塞队列因为超时而返回 null,timedOut 设为空
// 下次循环会进入
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
// Worker 退出方法
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
// (1) 将此 worker 从worker列表中删除
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
tryTerminate();
// (2) 如果 worker 数量不足 corePoolSize, 还会增加 Worker
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);
}
}