execute
public void execute(Runnable command) {
//(1) 如果任务为null,则抛出NPE异常
if (command == null)
throw new NullPointerException();
//(2)获取当前线程池的状态+线程个数变量的组合值
int c = ctl.get();
//(3)当前线程池线程个数是否小于corePoolSize,小于则开启新线程运行
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//(4)如果线程池处于RUNNING状态,则添加任务到阻塞队列
if (isRunning(c) && workQueue.offer(command)) {
//(4.1)二次检查
int recheck = ctl.get();
//(4.2)如果当前线程池状态不是RUNNING则从队列删除任务,并执行拒绝策略
if (! isRunning(recheck) && remove(command))
reject(command);
//(4.3)否者如果当前线程池线程空,则添加一个线程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//(5)如果队列满了,则新增线程,新增失败则执行拒绝策略
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);
// Check if queue empty only if necessary.
// 如果状态值 >= SHUTDOWN (不接新任务&不处理队列任务)
// 并且 如果 !(rs为SHUTDOWN 且 firsTask为空 且 阻塞队列不为空)
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
// 返回false
return false;
for (;;) {
//获取线程数wc
int wc = workerCountOf(c);
// 如果wc大与容量 || core如果为true表示根据corePoolSize来比较,否则为maximumPoolSize
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
// 增加workerCount(原子操作)
if (compareAndIncrementWorkerCount(c))
// 如果增加成功,则跳出
break retry;
// wc增加失败,则再次获取runState
c = ctl.get(); // Re-read ctl
// 如果当前的运行状态不等于rs,说明状态已被改变,返回重新执行
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 根据firstTask来创建Worker对象
w = new Worker(firstTask);
// 根据worker创建一个线程
final Thread t = w.thread;
if (t != null) {
// new一个锁
final ReentrantLock mainLock = this.mainLock;
// 加锁
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
// 获取runState
int rs = runStateOf(ctl.get());
// 如果rs小于SHUTDOWN(处于运行)或者(rs=SHUTDOWN && firstTask == null)
// firstTask == null证明只新建线程而不执行任务
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
// 如果t活着就抛异常
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
// 否则加入worker(HashSet)
//workers包含池中的所有工作线程。仅在持有mainLock时访问。
workers.add(w);
// 获取工作线程数量
int s = workers.size();
//largestPoolSize记录着线程池中出现过的最大线程数量
if (s > largestPoolSize)
// 如果 s比它还要大,则将s赋值给它
largestPoolSize = s;
// worker的添加工作状态改为true
workerAdded = true;
}
} finally {
mainLock.unlock();
}
// 如果worker的添加工作完成
if (workerAdded) {
// 启动线程
t.start();
// 修改线程启动状态
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
// 返回线启动状态
return workerStarted;
runWorker
final void runWorker(Worker w) {
// 拿到当前线程
Thread wt = Thread.currentThread();
// 拿到当前任务
Runnable task = w.firstTask;
// 将Worker.firstTask置空 并且释放锁
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
// 如果task或者getTask不为空,则一直循环
while (task != null || (task = getTask()) != null) {
// 加锁
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
// return ctl.get() >= stop
// 如果线程池状态>=STOP 或者 (线程中断且线程池状态>=STOP)且当前线程没有中断
// 其实就是保证两点:
// 1. 线程池没有停止
// 2. 保证线程没有中断
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
// 中断当前线程
wt.interrupt();
try {
// 空方法
beforeExecute(wt, task);
Throwable thrown = null;
try {
// 执行run方法(Runable对象)
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置空, 完成任务++, 释放锁
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
// 退出工作
processWorkerExit(w, completedAbruptly);
}
getTask
1 /**
2 * ThreadPoolExecutor:
3 */
4 private Runnable getTask() {
5 //timedOut标志位用来判断poll方法拿取任务是否超时了
6 boolean timedOut = false;
7
8 for (; ; ) {
9 int c = ctl.get();
10 //重新获取当前线程池的运行状态
11 int rs = runStateOf(c);
12
13 /*
14 如果当前线程池是SHUTDOWN状态,并且阻塞队列为空的时候;或者当前线程池的状态大于等于STOP
15 以上两种情况都会将工作线程-1,直接返回null。因为这两种情况下不需要
16 获取任务了。工作线程-1后,后续会在processWorkerExit方法中从workers集合中剔除掉这个Worker等待GC的
17 */
18 if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
19 decrementWorkerCount();
20 return null;
21 }
22
23 /*
24 走到这里说明当前线程池要么是RUNNING状态,要么是SHUTDOWN状态但是阻塞队列不为空(SHUTDOWN状态还是要
25 处理阻塞队列中的任务的)
26
27 重新获取当前线程池的工作线程数
28 */
29 int wc = workerCountOf(c);
30
31 /*
32 timed标志位表示工作线程是否需要超时销毁
33 如果allowCoreThreadTimeOut设置为true(表示空闲的核心线程也是要超时销毁的),或者当前线程数大于
34 核心线程数(这个条件代表的是空闲的非核心线程是要被销毁的,如果allowCoreThreadTimeOut为false,
35 那么线程池中最多保留“传进线程池中的核心线程数”个线程),就将timed置为true
36 */
37 boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
38
39 /*
40 如果当前工作线程数大于最大线程数,可能是调用了setMaximumPoolSize方法,把最大线程数改小了(走到这里
41 说明addWorker方法运行成功,而在addWorker方法中的第34行代码处已经判断了大于最大线程数的情况);
42 timedOut为true说明当前已经不是第一次循环了,在上次循环中已经发生了poll的超时。所以总结来说这个if条件的意思是:
43 <1.1>如果当前工作线程数大于最大线程数
44 <1.2>或者当前线程处于空闲状态并且是需要被销毁的
45 <2.1>并且当前工作线程要有多于一个
46 <2.2>或者当前阻塞队列是空的
47 满足上面两个条件,就将工作线程-1,去掉当前这个多余的线程,然后直接返回
48 */
49 if ((wc > maximumPoolSize || (timed && timedOut))
50 && (wc > 1 || workQueue.isEmpty())) {
51 //这里的方法和decrementWorkerCount方法的区别是不会死循环去一直CAS尝试,如果失败了就直接返回false
52 if (compareAndDecrementWorkerCount(c))
53 return null;
54 //如果CAS-1失败了,就进入到下次循环中继续判断即可
55 continue;
56 }
57
58 try {
59 /*
60 如果timed为true,则通过poll方法进行限时拿取(超过keepAliveTime时间没有拿取到,就直接返回null),
61 否则通过take方法进行拿取(如果阻塞队列为空,take方法在此时就会被阻塞住,也就是本线程会被阻塞住,直到
62 阻塞队列中有数据了。也就是说如果timed为false的话,这些工作线程会一直被阻塞在这里)
63 */
64 Runnable r = timed ?
65 workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
66 workQueue.take();
67 if (r != null)
68 //如果拿取到任务了,就直接返回给Worker处理
69 return r;
70 /*
71 走到这里说明发生了poll超时,那么将timedOut标志位置为true,进入到下一次循环中重试
72 (大概率会走到第53行代码处返回null)
73 */
74 timedOut = true;
75 } catch (InterruptedException retry) {
76 //如果在阻塞的过程中发生了中断,那么将timedOut置为false,也进入到下一次循环中重试
77 timedOut = false;
78 }
79 }
80 /*
81 以上的逻辑说明了:核心线程和非核心线程的区别并不是在Worker中有个表示是否是核心线程的属性,Worker是无状态的,
82 每个Worker都是一样的。而区分是通过判断当前工作线程数是否大于核心线程数来进行的(因为只有阻塞队列满了的时候
83 才会去创建新的非核心线程,也就会使工作线程数大于核心线程数)。如果大于,那么不管之前这个线程到底是核心线程
84 还是非核心线程,现在我就认定当前这个线程就是“非核心线程“,那么等这个“非核心线程”空闲时间超过keepAliveTime后,
85 就会被销毁
86 */
87 }