线程池添加线程成功就会调用 t.start() 方法启动Worker对象中线程,会去执行Worker对象中的run方法,run方法实际执行的是 runWorker(this) 方法。
// 执行任务
final void runWorker(Worker w) {
// 获取当前工作线程
Thread wt = Thread.currentThread();
// 获取Worker对象中封装的任务
Runnable task = w.firstTask;
// 将Worker的firstTask置为null
w.firstTask = null;
// 将Worker的state置为0,代表可以被中断
w.unlock(); // allow interrupts
// 任务执行时,勾子函数中是否出现异常标识位
boolean completedAbruptly = true;
try {
// 获取任务的第一个方式,就是执行execute方法、submit方法,传入的任务直接处理
// 获取任务的第二个方式,就是从工作队列中获取任务执行
while (task != null || (task = getTask()) != null) {
// 加锁,在SHUTDOWN状态下,当前线程不允许被中断
// 并且Worker内部实现的锁,并不是重入锁,因为在中断时,也需要对Worker进行加锁,不能获取就代表当前线程正在执行任务
w.lock();
// 如果线程池状态发生了改变,变为了STOP状态,必需将当前线程中断
// 第一个判断条件:判断当前线程池状态是否是STOP状态
if ((runStateAtLeast(ctl.get(), STOP)
// 第二个判断条件: 查看中断标记位,并归位,如果为false,说明不是STOP,反之true,需要再次查看是否是并发操作导致线程池为STOP
|| (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP)))
// 第三个判断条件: 查询当前线程的中断标记位,如果是false,就执行中断
&& !wt.isInterrupted())
// 将中断标志置为true
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
task = null;
// 执行任务的任务个数加一
w.completedTasks++;
// 将state标识置为0
w.unlock();
}
}
// 如果勾子函数有异常是不会走到这里的
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
// 从工作队列中获取任务
private Runnable getTask() {
// 标识(非核心线程可以干掉)
boolean timedOut = false; // Did the last poll() time out?
// 死循环
for (;;) {
// ==================判断线程池状态=======================
// 获取ctl标识
int c = ctl.get();
// 获取线程池的状态
int rs = runStateOf(c);
// 如果进入if,需要干掉当前工作线程
// 线程池状态为 SHUTDOWN、 STOP
// 如果线程池状态大于等于STOP,需要移除掉当前工作线程
// 如果线程池状态为SHUTDOWN,并且工作线程为空,需要移除掉当前工作线程
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
// 当前工作线程计数器减一
decre