1. ThreadPoolExecutor 类图
Java 中线程池都是基于 ThreadPoolExecutor 实现的
2. ThreadPoolExecutor 类核心属性
public class ThreadPoolExecutor extends AbstractExecutorService {
// 线程池属性值,高3位表示运行状态,低29位表示工作线程数
// 初始化运行状态为 RUNNING ,工作线程数为0
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// 任务队列
private final BlockingQueue<Runnable> workQueue;
// 全局锁
private final ReentrantLock mainLock = new ReentrantLock();
// 工作线程集合
private final HashSet<Worker> workers = new HashSet<Worker>();
// 线程池的终止条件
private final Condition termination = mainLock.newCondition();
// 线程池中曾经最大的线程数
private int largestPoolSize;
// 线程池任务完成计数器
private long completedTaskCount;
// 线程工厂
private volatile ThreadFactory threadFactory;
// 拒绝策略,任务队列和线程都满时执行的策略
private volatile RejectedExecutionHandler handler;
// 线程存活时间
private volatile long keepAliveTime;
// 是否允许核心线程超时销毁
private volatile boolean allowCoreThreadTimeOut;
// 核心线程数
private volatile int corePoolSize;
// 最大线程数
private volatile int maximumPoolSize;
// 默认拒绝策略为 AbortPolicy
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
// 获取运行状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 获取工作线程数
private static int workerCountOf(int c) { return c & CAPACITY; }
// 获取 ctl 的 int 类型的数值
private static int ctlOf(int rs, int wc) { return rs | wc; }
// ......
}
2.1 线程池的运行状态
| 状态 | 描述 |
|---|---|
| RUNNING | 正常状态,允许新任务加入,正常处理任务队列中的任务 |
| SHUTDOWN | 关闭状态,不允许新任务加入,正常处理任务队列中的任务 |
| STOP | 停止状态,不允许新任务加入,不处理任务队列中的任务,中断执行中的任务 |
| TIDYING | 整理状态,所有任务结束,工作线程数为0,准备执行 terminated() 方法 |
| TERMINATED | 终止状态,terminated() 方法执行完成,线程池销毁 |
2.2 拒绝策略
- AbortPolicy:直接抛出异常
- CallerRunsPolicy:只有调用者所在线程来执行任务
- DiscardOldestPolicy:丢弃任务队列最近一个待执行任务,然后调用
execute()方法处理任务 - DiscardPolicy:不处理,丢弃任务
3. Worker 工作线程类(内部类)
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
// ......
// 执行任务的线程
final Thread thread;
// 线程创建时执行的初始任务,可能为 null
Runnable firstTask;
// 线程任务完成计数器
volatile long completedTasks;
Worker(Runnable firstTask) {
// 设置同步状态为-1
// 避免执行 runWorker() 方法前被中断
setState(-1);
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
// 委托给外部类(ThreadPoolExecutor)的 runWorker() 方法执行当前线程的任务
public void run() {
runWorker(this);
}
// ......
}
Worker 内部类继承了 AbstractQueuedSynchronizer 类实现了互斥锁,主要是为了执行中的任务不被 ThreadPoolExecutor 中断,保证任务正常执行完成
4. 构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
// ......
}
-
corePoolSize:核心线程数
-
maximumPoolSize:最大线程数,如果线程池使用了无界的任务队列,该参数失效
-
keepAliveTime:线程存活时间,工作线程空闲(任务队列无任务可获取)时,保持存活的时间
-
unit:线程存活时间的单位
-
workQueue:任务队列,保存等待执行的任务的阻塞队列
-
threadFactory:创建线程的工厂
-
handler:拒绝策略,当线程和任务队列都满时需要采取一种策略处理提交的任务
5. 提交任务
5.1 execute 提交任务
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
// 如果工作线程数小于核心线程数
// 则创建线程执行任务
if (addWorker(command, true))
return;
c = ctl.get();
}
// 工作线程数小于核心线程数时
// 如果线程池是正常运行状态,添加任务到任务队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 双重检查,原因:
// 1. 任务添加到任务队列的过程中,工作线程销毁了
// 2. 任务添加到任务队列的过程中,线程池被关闭了
if (! isRunning(recheck) && remove(command))
// 双重检查不通过,移除任务后,调用拒绝任务方法
reject(command);
else if (workerCountOf(recheck) == 0)
// 如果工作线程数为0则创建线程
// 执行到该处,任务还在任务队列中,因此工作线程数为0的情况下需要创建线程
addWorker(null, false);
}
// 任务队列满了,创建非核心线程
else if (!addWorker(command, false))
// 创建非核心线程失败,调用拒绝任务方法
reject(command);
}
5.2 addWorker 添加线程
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
// 1. rs > SHUTDOWN 时,线程池为 STOP、TIDYING、TERMINATED 状态,不允许创建线程,返回 false
// 2. rs >= SHUTDOWN && firstTask != null 时,线程池为 SHUTDOWN、STOP、TIDYING、TERMINATED 状态,不允许添加任务,返回 false
// 3. rs >= SHUTDOWN && workQueue.isEmpty() 时,线程池为 SHUTDOWN、STOP、TIDYING、TERMINATED 状态且任务列表为空,不需要创建线程,返回 false
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
// 1. 如果工作线程数大于等于最大线程容量,返回 false
// 2. 创建核心线程时,如果工作线程数大于等于核心线程数,返回 false
// 3. 创建非核心线程时,如果工作线程数大于等于最大线程数,返回 false
return false;
if (compareAndIncrementWorkerCount(c))
// CAS 添加工作线程数失败,重新执行 addWorker() 方法
break retry;
c = ctl.get();
if (runStateOf(c) != rs)
// 线程池状态发生变化,重新执行 addWorker() 方法
continue retry;
}
}
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 {
int rs = runStateOf(ctl.get());
// 再次检查线程池运行状态
// 1. 如果是 RUNNING 状态,则继续创建线程
// 2. 如果是 SHUTDOWN 状态且初始任务为空,则继续创建线程
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
// 预先检查线程是否可启动
if (t.isAlive())
throw new IllegalThreadStateException();
// 添加线程到工作线程集合
workers.add(w);
int s = workers.size();
// 更新 largestPoolSize
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
// 释放全局锁
mainLock.unlock();
}
if (workerAdded) {
// 添加工作线程成功,启动线程
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
// 工作线程启动失败时
// 1. 移除线程
// 2. 工作线程数减1
// 3. 尝试终止线程池
addWorkerFailed(w);
}
return workerStarted;
}
6. 任务的执行
6.1 runWorker 工作线程执行
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
// 调用释放锁方法,允许中断线程
w.unlock();
// 工作线程是否异常结束
boolean completedAbruptly = true;
try {
// 从任务队列循环获取任务执行
while (task != null || (task = getTask()) != null) {
// 获取锁,避免执行任务过程中被中断
w.lock();
// 1. 如果线程池是 STOP、TIDYING、TERMINATED 状态,且当前工作线程未标记中断,则需要标记中断
// 2. 如果线程池是 RUNNING、SHUTDOWN 状态,且当前工作线程已标记中断,则需要取消标记中断
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;
// 计数器加1
w.completedTasks++;
// 释放锁
w.unlock();
}
}
completedAbruptly = false;
} finally {
// 将工作线程移除
processWorkerExit(w, completedAbruptly);
}
}
6.2 getTask 获取任务
private Runnable getTask() {
// 判断是否已执行超时获取任务
boolean timedOut = false;
// 循环执行获取任务逻辑
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// 下列情况下减少工作线程数,获取任务为空:
// 1. 线程池状态为 STOP、TIDYING、TERMINATED
// 2. 线程池状态为 SHUTDOWN 并且任务队列为空
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// 工作线程获取任务的方式:
// 1. 超时获取
// 2. 阻塞获取
// 超时获取任务的依据:
// 1. 允许任何线程都超时获取
// 2. 工作线程数大于设置的核心线程数
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// 下列情况下减少工作线程数,获取任务为空:
// 1. 工作线程数大于1且大于最大线程数(最大线程数可以由 setMaximumPoolSize 方法更改)
// 2. 工作线程数大于最大线程数且任务队列为空
// 3. 已超时获取任务且工作线程数大于1
// 4. 已超时获取任务且任务队列为空
if ((wc > maximumPoolSize || (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;
// 标记已执行超时获取任务
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
6.3 processWorkerExit 移除工作线程
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// 如果工作线程是非正常退出循环获取任务逻辑
// 那么工作线程数还未减少,需要执行减少
if (completedAbruptly)
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
// 获取全局锁
mainLock.lock();
try {
// 移除工作线程时,将该线程已完成的任务数添加进线程池完成的任务数
completedTaskCount += w.completedTasks;
// 工作线程集合中移除该线程
workers.remove(w);
} finally {
// 释放全局锁
mainLock.unlock();
}
// 尝试终止线程池
tryTerminate();
int c = ctl.get();
// 如果线程池状态为 RUNNING、SHUTDOWN
if (runStateLessThan(c, STOP)) {
// 如果线程是正常退出
if (!completedAbruptly) {
// 计算出线程池需要保持的最小线程数
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
// 工作线程数大于等于需要保持的最小线程数,退出不需要新增线程
if (workerCountOf(c) >= min)
return;
}
// 新增一个未指定初始任务的非核心工作线程
// 新增的原因:
// 1. 当前工作线程非正常退出,需要换个新的线程
// 2. 线程池的工作线程数小于需要保持的最小线程数,需要添加个线程
addWorker(null, false);
}
}
7. 关闭线程池
7.1 shutdown 关闭线程池(友好式)
不允许新任务加入,正常处理任务队列中的任务
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
// 获取全局锁
mainLock.lock();
try {
// 检查是否有关闭线程池的权限
checkShutdownAccess();
// 设置线程池状态为 SHUTDOWN
advanceRunState(SHUTDOWN);
// 尝试中断工作线程
interruptIdleWorkers();
// 回调线程池关闭方法,JDK 为 ScheduledThreadPoolExecutor 提供的
onShutdown();
} finally {
// 释放全局锁
mainLock.unlock();
}
// 尝试终止线程池
tryTerminate();
}
7.2 shutdownNow() 关闭线程池(暴力式)
不允许新任务加入,不处理任务队列中的任务,中断执行中的任务
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
// 获取全局锁
mainLock.lock();
try {
// 检查是否有关闭线程池的权限
checkShutdownAccess();
// 设置线程池状态为 STOP
advanceRunState(STOP);
// 直接中断工作线程
interruptWorkers();
// 获取任务队列的任务列表
tasks = drainQueue();
} finally {
// 释放全局锁
mainLock.unlock();
}
// 尝试终止线程池
tryTerminate();
return tasks;
}
7.3 tryTerminate 尝试终止线程池
final void tryTerminate() {
for (;;) {
int c = ctl.get();
// 下列情况直接退出终止线程池:
// 1. 线程池状态为 RUNNING
// 2. 线程池状态为 TIDYING、TERMINATED
// 3. 线程池状态为 SHUTDOWN 且任务列表不为空
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
// 当工作线程数不为0,只有尝试终止一个工作线程的资格
if (workerCountOf(c) != 0) {
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
// 获取全局锁
mainLock.lock();
try {
// 设置线程池状态为 TIDYING 和工作线程数为0
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
// 调用终止方法
terminated();
} finally {
// 设置线程池状态为 TERMINATED 和工作线程数为0
ctl.set(ctlOf(TERMINATED, 0));
// 唤醒所有等待线程终止条件的线程
termination.signalAll();
}
return;
}
} finally {
// 释放全局锁
mainLock.unlock();
}
}
}
满足下列条件时才能进一步终止线程池:
- 线程池状态为 SHUTDOWN 时,工作线程数为0,任务队列为空
- 线程池状态为 STOP 时,工作线程数为0