ThreadPoolExecutor源码解析
- 一、概述
- 二、ThreadPoolExecutor 执行任务示意图
- 三、ThreadPoolExecutor 源码分析
- 1. 构造参数的含义
- 2. 常量
- 3. 提交任务: execute()、submit()
- 4. addWorker(Runnable firstTask, boolean core) 方法
- 5. Worker 类
- 6. runWorker(this)
- 7. getTask()
- 8. processWorkerExit(Worker w, boolean completedAbruptly)
- 9. tryTerminate()
- 10. shutdown()、shutdownNow ()
- 四、execute(Runnable) 的执行流程
一、概述
版本: JDK1.8
文章链接如下:
在上面两篇文章中,我们分析了 ThreadPoolExecutor 的实现原理和通过 ThreadPoolExecutor 实现的几种具有不同特点的线程池。下面我们就分析一下 ThreadPoolExecutor 具体的实现。
二、ThreadPoolExecutor 执行任务示意图
三、ThreadPoolExecutor 源码分析
主要分析以下几部分:
- 构造参数的含义;
- 常量的意义;
- 提交任务的方法;
execute()
不带返回值submit()
带返回值
addWorker(Runnable firstTask, boolean core)
方法Worker
类runWorker()
方法
1. 构造参数的含义
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
// do something
}
参数含义参考文章:Executor框架(二) — 线程池原理浅析
2. 常量
/**
* 一个同时记录线程池状态和线程个数的变量。
* @desc: Integer 的位数为 32 位,其中高 3 位表示线程池的状态,低 29 位表示线程的个数。
* 默认为 RUNNING 状态,线程个数为 0。
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; //29
/**
* 1<<29 = 00100000 00000000 00000000 00000000
* (1<<29) - 1 = 00011111 11111111 11111111 11111111
* ~CAPACITY(取反) = 11100000 00000000 00000000 00000000
*/
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState: 高3位代表线程池的状态; 低29位代表线程的数量(线程数最多为(2^29)-1 )
private static final int RUNNING = -1 << COUNT_BITS; //11100000 00000000 00000000 00000000
private static final int SHUTDOWN = 0 << COUNT_BITS; //00000000 00000000 00000000 00000000
private static final int STOP = 1 << COUNT_BITS; //00100000 00000000 00000000 00000000
private static final int TIDYING = 2 << COUNT_BITS; //01000000 00000000 00000000 00000000
private static final int TERMINATED = 3 << COUNT_BITS; //01100000 00000000 00000000 00000000
// Packing and unpacking ctl
// 通过取反(获得前三个高位全为1),然后和传入的c进行&运算,可判断出线程池目前是什么状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
//通过与运算可以算出线程数
private static int workerCountOf(int c) { return c & CAPACITY; }
// 计算 ct l的值,用线程池状态和线程个数进行或运算
private static int ctlOf(int rs, int wc) { return rs | wc; }
注: 如果想查看上面变量的二进制形式,可以通过方法 Integer.toBinaryString(int i)
查看。
补码的相关知识
计算机只能进行加法运算,为了处理负数的问题,引入的补码的相关概念。
-
一个int类型的整数占用了4个字节,共 32 bits,其中最高位的bit代表符号位(0代表正数;1代表负数),剩余 31bits 代表数字部分;数字部分都用补码来表示。
-
原码、反码、补码的转换规则:
原码:数字转换为二进制后的数字;
反码:如果是正数,则反码=原码;如果是负数,除符号位不变,其它位按照原码各位进行取反;
补码:如果是正数,则补码=反码=原码;如果是负数,则在反码的基础上加1;
详细可参考这篇文章: 数据结构 — 原码, 反码, 补码 详解 - 第三部分
示例: private static final int RUNNING = -1 << COUNT_BITS;
COUNT_BITS = 29
-1原码:10000000,00000000,00000000,00000001 (最高位为1,代表负数)
-1反码: 11111111 , 11111111 , 11111111 , 11111110 (最高位不动,其余各位与原码取反)
-1补码: 11111111 , 11111111 , 11111111 , 11111111 (在反码的基础上加1)
-1 << 29:11100000,00000000,00000000,00000000 (补码各位整体向左移动29位,右边用0补齐位置)
runState 几种状态的说明
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. (所有任务已终止,workerCount为0,处于TIDYING状态的线程将调用钩子方法terminated())
TERMINATED
:terminated() has completed. (terminated()方法完成)
runState
状态转化的过程:
RUNNING -> SHUTDOWN
:On invocation of shutdown(), perhaps implicitly in finalize().
(RUNNING or SHUTDOWN) -> STOP
:On invocation of shutdownNow().
SHUTDOWN -> TIDYING
:When both queue and pool are empty.
STOP -> TIDYING
:When pool is empty.
TIDYING -> TERMINATED
:When the terminated() hook method has completed.
3. 提交任务: execute()、submit()
ThreadPoolExecutor
线程池提交任务有两种方式:
- 不带返回值:
execute(Runnable)
- 带返回值:
submit(Callable)
、submit(Runnable)
execute()
// ThreadPoolExecutor.class
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
// 获取表示线程池状态和线程个数的组合变量 ctl
int c = ctl.get();
// 如果线程个数小于核心线程数,则创建线程并执行当前任务
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
// 代码执行到这里说明:1. 线程个数>=核心线程数;2.执行 addWorder 方法失败)
// 如果线程池处于 RUNNAING 状态,就把任务添加到阻塞队列中
if (isRunning(c) && workQueue.offer(command)) {
// 再次获取组合变量 ctl,做二次检查(因为线程池的状态可能已经发生了改变)
int recheck = ctl.get();
// 如果线程池状态不是 RNUUAING 状态,就把该任务从阻塞任务队列中移除,并执行拒绝策略
if (! isRunning(recheck) && remove(command))
reject(command);
// 如果线程池中线程个数为0(则刚才的任务肯定在阻塞队列里),就新建一个线程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 代码执行到这里,说明任务无法添加进队列(队列满了),则尝试新建一个线程处理这个任务;
// 如果线程创建失败,则说明“线程个数达到最大线程数”或者“线程池处于SHUTDOWN状态”,执行拒绝策略
else if (!addWorker(command, false))
reject(command);
}
submit()
submit()
接收两种参数:Runnable 不带返回值
、Callable 带返回值
// AbstractExecutorService.class
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
// 构造一个FutureTask实例,作用是获得返回值
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask); //最后还是调用
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
// 构造一个FutureTask实例,作用是获得返回值
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
// Callable.class
public interface Callable<V> {
V call() throws Exception;
}
4. addWorker(Runnable firstTask, boolean core) 方法
从 execute()
方法中可以看到,加入任务后会执行 addWorker()
方法。
// ThreadPoolExecutor.class
private boolean addWorker(Runnable firstTask, boolean core) {
retry: //这是个跳出外层循环的标记.
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
// 由上面“常量”部分可知,SHUTDOWN 状态下,线程池不接收新任务,但会处理队列中的任务。
// 条件 (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()),代表线程池处于shutdown,且 firstTask 为 null, 同时队列不为空的条件下,允许创建 worker.
// 在线程池状态处于非 RUNNING 的状态下,只有以下一种情况((rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) 是允许创建worker线程的,其他场景都不允许。
if (rs >= SHUTDOWN && // rs >= SHUTDOWN 代表rs 的状态是除 RUNNING 的所有状态
! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()))
return false;
for (;;) { //自旋
// 获取当前线程池的线程数
int wc = workerCountOf(c);
// 根据core的值来确定当前线程数是否超过线程数的边界(core ? corePoolSize : maximumPoolSize),超过了则不创建新的worker.
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
// 进入这里,代表当前线程数超过了线程数的边界,所以不创建新的worker.
return false;
// 通过 CAS来使工作线程数+1 (如果这里操作失败,则表示有并发操作)
if (compareAndIncrementWorkerCount(c))
break retry;
// 如果上面的CAS操作没有成功,说明存在并发操作,因此需要重新读取 ctl 值进行状态判断
c = ctl.get(); // Re-read ctl
// 判断当前的线程状态是否发生变化?(分两种情况:变化了、没变化)
if (runStateOf(c) != rs) // runStateOf(c) != rs 这个判断操作主要是看当前线程池的状态变没变,
continue retry; // 执行到这里面,说明线程状态发生了变化,则回到外层的for循环重新执行。
// 如果没有执行 `continue retry` 方法,说明线程状态没变,因此重新执行内层循环,重新执行CAS操作。
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 把 task 封装成 worker。(通过线程工厂创建线程时,会把任务设置到 Thread 的 target 属性上,后续在执行线程的 start 方法时,就会执行对应的任务的 run 方法。)
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
// 这里会获取全局锁,所以如果频繁执行创建Worker(),会出现性能瓶颈。
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
// 如果线程池处于 Running 状态 或者 线程池处于 shutdown 状态且 firstTask=null(执行任务队列中的任务)
if (rs < SHUTDOWN || //rs < SHUTDOWN表示线程池处于Running 状态
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w); // 将新建的 worker 添加到 worker 集合中
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s; // largestPoolSize 记录 workers 中个数存在过的最大值。
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start(); //启动线程
workerStarted = true;
}
}
} finally {
if (! workerStarted) //如果工作线程没有启动
addWorkerFailed(w); //则回滚之前的设置;
}
return workerStarted;
}
/**
* Rolls back the worker thread creation.
* - removes worker from workers, if present
* - decrements worker count
* - rechecks for termination, in case the existence of this worker was holding up termination
*/
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
workers.remove(w); // 1.将worker从workers中移除;
decrementWorkerCount(); // 2.将cls中的worker数量还原;
tryTerminate(); // 3.重新检测线程池的状态
} finally {
mainLock.unlock();
}
}
5. Worker 类
// ThreadPoolExecutor.Worker.class
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
// 此处newThread(this) 传入的this即代表worker本身,所以当线程启动时,会执行worker类里面的 run() 方法.
this.thread = getThreadFactory().newThread(this);
}
public void run() {
runWorker(this); //调用// ThreadPoolExecutor.runWorker()
}
// Thread.class
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
6. runWorker(this)
// ThreadPoolExecutor.class
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask; //获取当前线程任务
w.firstTask = null;
// 把 status 设置为 0,允许中断;与Worker构造那里的setState(-1)遥相呼应
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
// 此处加锁是为了避免任务运行期间,其他线程调用 shutdown 方法关闭线程池中正在执行任务的线程。
w.lock();
// 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(); // 执行任务,这里的 task 是 execute() 方法中传入的 Runnable 对象。
} 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); // 配合 beforeExecute(wt, task) 可以计算出每个任务的耗时。
}
} finally {
task = null;
// Worker.completedTasks 字段表示每个线程处理的 task 数量,可以作为线程使用程度的参考。
w.completedTasks++;
w.unlock(); //释放当前线程的独占锁
}
}
completedAbruptly = false;
} finally {
// 注意:执行到这里说明 task == null 并且 getTask()返回 null。
// 说明当前线程池线程数过多(任务过少,导致不是每个线程都能从队列中获取数据。),因此可以把多于corePoolSize 数量的工作线程干掉。
processWorkerExit(w, completedAbruptly);
}
}
protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }
protected void terminated() { }
小结:
在分析之前,需要了解一下线程池在几种 runState 状态的特点。
RUNNING
:接收新任务并处理队列中的任务。
SHUTDOWN
:不接收新任务,但会处理队列中的任务。
STOP
: 不接收新任务,不处理队列中的任务,并中断正在处理的任务。
TIDYING
:所有任务已终止,workerCount为0,处于TIDYING状态的线程将调用钩子方法terminated()。
TERMINATED
:terminated()方法完成。
// 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();
}
上面这部分代码的判断逻辑分为两种情况:
-
runStateAtLeast(ctl.get(), STOP) && !wt.isInterrupted()
提示: 线程池STOP 状态下,既不接收新的 task,也不处理队列中的 task;
在STOP状态下,如果当前线程不阻断 (即wt.isInterrupted() = false
),则需要调用wt.interrupt()
去阻断当前线程处理任何 task; -
Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()
当执行到这个判断逻辑时,代表当前线程池的状态还未达到 STOP 状态,则需要确保线程没有中断(因为当前线程需要保持处理task的能力)。- 第1步:执行
Thread.interrupted()
会清除当前线程的阻断状态(确保线程非阻断)。 - 第2步:执行
runStateAtLeast(ctl.get(), STOP)
是为了再次验证线程池的状态,因为可能会有 shutdownNow() 的情况。 - 当线程池状态又满足第2步时(即要满足STOP状态下线程池的特性),由于第1步调用
Thread.interrupted()
会清除线程阻断的状态,所以wt.isInterrupted()
必然返回 false,所以会重新执行wt.interrupt()
进行阻断。
- 第1步:执行
7. getTask()
// ThreadPoolExecutor.class
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.
// 以下返回 null 的场景请参考下面小结部分的第 2,3 两点。
// 1.线程池状态 >= STOP
// 2.线程池状态 >= SHUTDOWN,且队列为空。
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
// 获取当前的线程个数
int wc = workerCountOf(c);
// Are workers subject to culling?
// 线程的超时机制:如果线程处于闲置状态,且闲置时间超过了设置的等待时间(keepAliveTime),线程就会被销毁。
// 如果allowCoreThreadTimeOut=true:会作用于所有线程(核心线程 + 非核心线程)
// 如果allowCoreThreadTimeOut=false:仅作用于非核心线程
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// 下面返回 null 的场景,请参考下面小结部分的第 1,4 两点。
// 第1点:当 wc > maximumPoolSize 满足条件时,wc > 1 也成立;
// 第4点:获取 task 超时时,需要判断当前队列是否为空;队列不为空,则线程池至少要存在一个线程;队列为空,则线程池可以不存在线程;
if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
// 从队列中获取Runnable元素,会超时的,使用 poll(); 不会超时的,使用 take();
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true; // 这种一定是超时导致的,所以timedOut设置为true
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
小结:
getTask()
方法返回 null 的情况主要有以下4点:
-
当前线程总数超过了 maximumPoolSize 限制;
正常情况下,线程池的线程数量是不会超过 maximumPoolSize 大小的,但是
ThreadPoolExecutor.setMaximumPoolSize()
可以动态设置新的最大线程数,所以就可能存在当前线程数超过 maximumPoolSize 的情况)。 -
线程池的状态处于STOP。
-
线程池的状态处于SHUTDOWN,且队列为空。
为何线程池状态处于SHUTDOWN时,需要对队列进行判空?
线程池为SHUTDOWN状态时,还是会继续处理队列中的数据,即队列非空的情况下,仍能从getTask()
, 方法中取出 task,而非 null ,所以需要对队列进行判空。 -
超时的条件( 1.当 worker 所在线程获取 task 超时(即队列为空)时,2.或者线程闲置超时要中止时);
- 如果任务队列非空,要保证当前 worker 线程不是线程池中最后一个线程;
- 如果任务队列为空,当前线程是线程池中的最后一个线程也无妨(即任务队列为空,当前 worker 线程关闭就关闭了,没影响) ;
8. processWorkerExit(Worker w, boolean completedAbruptly)
// ThreadPoolExecutor.class
private void processWorkerExit(Worker w, boolean completedAbruptly) {
//任务是否是突然完成啦,完成就将工作线程数量-1
//如果completedAbruptly=true,则说明线程执行时出现异常,需要将workerCount数量减一
//如果completedAbruptly=false,则说明在 getTask() 方法中已经对workerCount进行减一,这里不用再减
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks; //计算线程池完成的任务总个数
workers.remove(w); //从 workers 集合中删除当前 worker 线程
} finally {
mainLock.unlock();
}
tryTerminate(); //尝试把线程池的状态设置为 TERMINATED
int c = ctl.get();
if (runStateLessThan(c, STOP)) { //满足条件的线程池状态:RUNNING、SHUTDOWN
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
//新建 worker 线程的条件:
//1.当前线程数小于核心线程数
//2.任务队列不为空但没有运行的线程了(允许核心线程超时的情况下)
addWorker(null, false);
}
}
9. tryTerminate()
// ThreadPoolExecutor.class
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//处于下面三种任意一种情况,不能把线程池的状态设为 TERMINATED
//1.RUNNING状态:不能终止线程池。
//2.TIDYING、TERMINATED状态:说明线程池已经处于正在终止的路上,不用再终止了。
//3.SHUTDOWN状态:且任务队列不为空,也不能终止线程池。
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 {
//设置线程池状态为TIDYING,如果设置成功,则调用 terminated() 方法
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated(); //线程池状态变为TERMINATED后
} finally {
ctl.set(ctlOf(TERMINATED, 0)); //将线程池状态设置为TERMINATED
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
10. shutdown()、shutdownNow ()
// ThreadPoolExecutor.class
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess(); //权限校验
advanceRunState(SHUTDOWN); //设置线程池状态为 SHUTDOWN
interruptIdleWorkers(); //中断所有空闲线程
onShutdown(); //子类实现的钩子方法
} finally {
mainLock.unlock();
}
tryTerminate(); // 尝试设置线程池状态为 TERMINATED
}
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t = w.thread;
//tryLock() 判断线程是否空闲
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess(); //权限校验
advanceRunState(STOP); //设置线程池状态为 STOP
interruptWorkers(); //中断所有线程
tasks = drainQueue(); //将任务队列中的任务移动到 tasks 中
} finally {
mainLock.unlock();
}
tryTerminate(); //尝试设置线程池状态为 TERMINATED
return tasks;
}
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted(); //直接执行中断
} finally {
mainLock.unlock();
}
}
四、execute(Runnable) 的执行流程
执行 execute(Runnable) 方法传入的 Runnable 又是如何被执行的呢?
-
在执行
execute(Runnable)
方法时,会将Runnable对象通过addWorker(Runnable firstTask, boolean core)
方法传入; -
在
addWorker(Runnable firstTask, boolean core)
方法中,通过创建Worker(Runnable firstTask)
对象将 Runnable 对象传入 Worker;在创建 Worker 对象时,会通过ThreadFactory.newThread(this)
方法构造一个线程,此时将外部的 Runnable 传递给具体线程的target
;// ThreadPoolExecutor.Worker.class Worker(Runnable firstTask) { setState(-1); // inhibit interrupts until runWorker this.firstTask = firstTask; // 此处newThread(this) 传入的this即代表worker本身,所以当线程启动时,会执行worker类里面的 run() 方法. this.thread = getThreadFactory().newThread(this); } // Thread.class public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }
-
在
addWorker(Runnable firstTask, boolean core)
方法中,创建完 Worker 对象后,会获取当前线程并启动;// ThreadPoolExecutor.Worker.class private boolean addWorker(Runnable firstTask, boolean core) { // ...省略部分代码 Worker w = new Worker(firstTask); //只要创建了一个新的Worker,就会伴随创建一个Thread final Thread t = w.thread; //获取线程 // ...省略部分代码 if (t != null) { // ...省略部分代码 if (workerAdded) { t.start(); //启动线程 workerStarted = true; } } // ...省略部分代码 return workerStarted; }
-
启动线程时,会执行 Thread 内的
run()
方法,在Thread.run()
方法中,会执行target.run()
方法,而 target 对象就是我们传入的 Worker 对象。// Thread.class public void run() { if (target != null) { target.run(); // 此处的 target 即是 Worker 对象 } }
-
第4步调用了
Worker.run()
方法后,会调用ThreadPoolExecutor.runWorker(this)
方法,在runWorker(this)
方法中会执行从execute(Runnable)
传递进来的 Runnable// ThreadPoolExecutor.Worker.class public void run() { runWorker(this); // } // ThreadPoolExecutor.class final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; //获取当前线程任务 // ...省略部分代码 while (task != null || (task = getTask()) != null) { // ...省略部分代码 beforeExecute(wt, task); task.run(); // 执行任务,这里的 task 是 execute() 方法中传入的 Runnable 对象。 afterExecute(task, thrown); // ...省略部分代码 } }