在调用start()方法,调用的就是worker的run方法,实际上调用的是runWorker()方法
public void run() {
// 这个是核心方法,worker启动后的逻辑从这里进入
runWorker(this);
}
简单的梳理runWorker的流程
- 如果构造worker的时候,指定了firstTask,那么首先执行firstTask。否则从队列中获取任务;
- Worker线程会循环的getTask(),然后去执行任务
- 如果getTask()为空,那么worker线程就会退出
- 在任务执行前后,可以自定义扩展beforeExecute与afterExecuter方法
- 如果检测到先吃池为STOP状态,并且线程还没有被中断过的话,进行中断处理
1.将初始执行task赋值给task
Runnable task = w.firstTask;
2.completedAbruptly:是否是突然退出; false 正常退出; 默认ture
boolean completedAbruptly = true;
3.条件判断
// 条件1: 指的是firstTask 不为 null.
// 条件2: 说明当前线程在queue中获取任务成功. 如果返回null。
// getTask是一个会阻塞线程的方法。说明当前线程需要执行退出逻辑
(task != null || (task = getTask()) != null)
// w 就是启动worker
final void runWorker(Worker w) {
// wt == w.thread。
Thread wt = Thread.currentThread();
// 将初始 执行 task 赋值给 task
Runnable task = w.firstTask;
// 清空当前 w.firstTask引用
w.firstTask = null;
// 为了初始化worker 的 state == 0 和 exclusiveOwnerThread == null
w.unlock(); // allow interrupts
// 是否是突然退出 ; false 正常退出
boolean completedAbruptly = true;
try {
// 条件1: 指的是firstTask 不为 null.
// 条件2: 说明当前线程在queue中获取任务成功. 如果返回null。
// getTask是一个会阻塞线程的方法。说明当前线程需要执行退出逻辑
while (task != null || (task = getTask()) != null) {
// worker加锁设置,为当前线程
// 为什么要设置独占锁? shutdown时会判断当前worker状态,根据独占锁是否空闲来判断当前worker是否正在工作
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
// 条件1: 说明线程池目前处于 STOP/TIDYING.TERMINATION 此时线程一定要给它一个中断信号
// 条件2: 前部分成立:说明当前线程池状态是>=STOP 且当前线程未设置中断状态;
// 后半部分:
// 强制刷新当前线程的中断标记 false, 有可能上一个task时,业务代码里面将当前线程的中断标记位设置为了true,且没有处理。
// 这里一定要强制刷新一下,不会影响到后面的task
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
//
wt.interrupt();
try {
// 钩子方法,留给子类实现
beforeExecute(wt, task);
// 表现异常情况,如果thrown不为空,表示 task运行过程中,向上层抛出异常了
Throwable thrown = null;
try {
// task 可能是 FutureTask 也可能是Runnable接口实现类
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++;
// worker处理完成一个任务后,会释放独占锁。然后再次到queue队列中获取任务
w.unlock();
}
}
// 什么情况执行到这里?
// 1. getTask() 返回null。 说明当前线程应该执行退出
// 2.
completedAbruptly = false;
} finally {
// task.run() 抛出异常,直接到这里
// 正常退出 completedAbruptly 为false
// 异常退出 completedAbruptly 为 true
processWorkerExit(w, completedAbruptly);
}
}
总结:runWorker
1.如果task不为空,则开始执行task方法
2.如果task为空,则通过getTask()再去取任务,并赋值给task,如果取到的Runnable不为空,则执行该任务;
3.执行完毕后,通过while循环继续getTask()取任务
4.如果getTask()取到的任务依然是空,那么整个runWorker()方法执行完毕;