1.execute干了哪些事情
-
1.1:首先判断任务是否为空
-
1.2:: 判断工作线程数是否小于核心线程个数,小于则新增核心线程去处理该任务,然后返回。ctl是一个AtomicInteger变量,高3位表示线程池状态,低29位表示工作线程个数。
-
1.3:如果核心线程个数已满,线程池状态是RUNNING状态,任务入队
1.3.1:判断线程池状态,线程状态不是RUNNING状态,删除队列中的任务,执行拒绝策略。
1.3.2:任务已经加到队列中了,但如果此时工作线程个数为0,则新增非核心线程去处理。
-
1.4:核心线程个数已满,队列已满,新增非核心线程去处理任务。新增非核心线程失败(超过maximumPoolSize个数),则执行拒绝策略。
public void execute(Runnable command) {
if (command == null)//任务为空,抛异常
throw new NullPointerException();
int c = ctl.get();//ctl是一个AtomicInteger变量,高3位表示线程池状态,低29位表示工作线程个数
if (workerCountOf(c) < corePoolSize) {//工作线程小于核心线程个数
if (addWorker(command, true))//新增核心线程处理任务
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {//核心线程个数已满,任务放入队列
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false)) //核心线程个数已满,队列已满,新增非核心线程处理
reject(command);
}
2.addWorker干哪些事情
-
2.1:判断线程池状态。
-
2.2:工作线程数加1。
-
2.3:创建Worker,Worker实现了Runnable。在new Worker时,会把当前的worker传入到thread中,然后赋值给worke的thread变量,当启动线程时,其实就是执行了传入的wroker的run的方法。
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
-
2.4:把:创建的worker放入到HashSet<Worker>中。
-
2.5:启动线程。执行的是 worker的run方法.
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
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 {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();//执行的是worker的run方法
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
3.runWorker干了哪些事情
-
3.1:执行传过来的任务。
-
3.2:循环从队列拿任务执行。
-
3.3::worker退出。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
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;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//worker退出
processWorkerExit(w, completedAbruptly);
}
}
4.getTask干了哪些事情
//什么情况下会返回null?
//1.rs >= STOP 成立说明:当前的状态最低也是STOP状态,一定要返回null了
//2.前置条件 状态是 SHUTDOWN ,workQueue.isEmpty()
//3.线程池中的线程数量 超过 最大限制时,会有一部分线程返回Null
//4.线程池中的线程数超过corePoolSize时,会有一部分线程 超时后,返回null。
private Runnable getTask() {
//表示当前线程获取任务是否超时 默认false true表示已超时
boolean timedOut = false; // Did the last poll() time out?
//自旋
for (;;) {
//获取最新ctl值保存到c中。
int c = ctl.get();
//获取线程池当前运行状态
int rs = runStateOf(c);
// Check if queue empty only if necessary.
//条件一:rs >= SHUTDOWN 条件成立:说明当前线程池是非RUNNING状态,可能是 SHUTDOWN/STOP....
//条件二:(rs >= STOP || workQueue.isEmpty())
//2.1:rs >= STOP 成立说明:当前的状态最低也是STOP状态,一定要返回null了
//2.2:前置条件 状态是 SHUTDOWN ,workQueue.isEmpty()条件成立:说明当前线程池状态为SHUTDOWN状态 且 任务队列已空,此时一定返回null。
//返回null,runWorker方法就会将返回Null的线程执行线程退出线程池的逻辑。
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
//使用CAS+死循环的方式让 ctl值 -1
decrementWorkerCount();
return null;
}
//执行到这里,有几种情况?
//1.线程池是RUNNING状态
//2.线程池是SHUTDOWN状态 但是队列还未空,此时可以创建线程。
//获取线程池中的线程数量
int wc = workerCountOf(c);
// Are workers subject to culling?
//timed == true 表示当前这个线程 获取 task 时 是支持超时机制的,使用queue.poll(xxx,xxx); 当获取task超时的情况下,下一次自旋就可能返回null了。
//timed == false 表示当前这个线程 获取 task 时 是不支持超时机制的,当前线程会使用 queue.take();
//情况1:allowCoreThreadTimeOut == true 表示核心线程数量内的线程 也可以被回收。
//所有线程 都是使用queue.poll(xxx,xxx) 超时机制这种方式获取task.
//情况2:allowCoreThreadTimeOut == false 表示当前线程池会维护核心数量内的线程。
//wc > corePoolSize
//条件成立:当前线程池中的线程数量是大于核心线程数的,此时让所有路过这里的线程,都是用poll 支持超时的方式去获取任务,
//这样,就会可能有一部分线程获取不到任务,获取不到任务 返回Null,然后..runWorker会执行线程退出逻辑。
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
//条件一:(wc > maximumPoolSize || (timed && timedOut))
//1.1:wc > maximumPoolSize 为什么会成立?setMaximumPoolSize()方法,可能外部线程将线程池最大线程数设置为比初始化时的要小
//1.2: (timed && timedOut) 条件成立:前置条件,当前线程使用 poll方式获取task。上一次循环时 使用poll方式获取任务时,超时了
//条件一 为true 表示 线程可以被回收,达到回收标准,当确实需要回收时再回收。
//条件二:(wc > 1 || workQueue.isEmpty())
//2.1: wc > 1 条件成立,说明当前线程池中还有其他线程,当前线程可以直接回收,返回null
//2.2: workQueue.isEmpty() 前置条件 wc == 1, 条件成立:说明当前任务队列 已经空了,最后一个线程,也可以放心的退出。
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
//使用CAS机制 将 ctl值 -1 ,减1成功的线程,返回null
//CAS成功的,返回Null
//CAS失败? 为什么会CAS失败?
//1.其它线程先你一步退出了
//2.线程池状态发生变化了。
if (compareAndDecrementWorkerCount(c))
return null;
//再次自旋时,timed有可能就是false了,因为当前线程cas失败,很有可能是因为其它线程成功退出导致的,再次咨询时
//检查发现,当前线程 就可能属于 不需要回收范围内了。
continue;
}
try {
//获取任务的逻辑
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
//条件成立:返回任务
if (r != null)
return r;
//说明当前线程超时了...
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
5.processWorkerExit干了哪些事情
private void processWorkerExit(Worker w, boolean completedAbruptly) {
//条件成立:代表当前w 这个worker是发生异常退出的,task任务执行过程中向上抛出异常了..
//异常退出时,ctl计数,并没有-1
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
//获取线程池的全局锁引用
final ReentrantLock mainLock = this.mainLock;
//加锁
mainLock.lock();
try {
//将当前worker完成的task数量,汇总到线程池的completedTaskCount
completedTaskCount += w.completedTasks;
//将worker从池子中移除..
workers.remove(w);
} finally {
//释放全局锁
mainLock.unlock();
}
tryTerminate();
//获取最新ctl值
int c = ctl.get();
//条件成立:当前线程池状态为 RUNNING 或者 SHUTDOWN状态
if (runStateLessThan(c, STOP)) {
//条件成立:当前线程是正常退出..
if (!completedAbruptly) {
//min表示线程池最低持有的线程数量
//allowCoreThreadTimeOut == true => 说明核心线程数内的线程,也会超时被回收。 min == 0
//allowCoreThreadTimeOut == false => min == corePoolSize
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
//线程池状态:RUNNING SHUTDOWN
//条件一:假设min == 0 成立
//条件二:! workQueue.isEmpty() 说明任务队列中还有任务,最起码要留一个线程。
if (min == 0 && ! workQueue.isEmpty())
min = 1;
//条件成立:线程池中还拥有足够的线程。
//考虑一个问题: workerCountOf(c) >= min => (0 >= 0) ?
//有可能!
//什么情况下? 当线程池中的核心线程数是可以被回收的情况下,会出现这种情况,这种情况下,当前线程池中的线程数 会变为0
//下次再提交任务时,会再创建线程。
if (workerCountOf(c) >= min)
return; // replacement not needed
}
//1.当前线程在执行task时 发生异常,这里一定要创建一个新worker顶上去。
//2.!workQueue.isEmpty() 说明任务队列中还有任务,最起码要留一个线程。 当前状态为 RUNNING || SHUTDOWN
//3.当前线程数量 < corePoolSize值,此时会创建线程,维护线程池数量在corePoolSize个。
addWorker(null, false);
}
}
6.shutdown干了哪些事情
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
tryTerminate();
}
7.shutdownNow干了哪些事情
public List<Runnable> shutdownNow() {
//返回值引用
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
//获取线程池全局锁
mainLock.lock();
try {
checkShutdownAccess();
//设置线程池状态为STOP
advanceRunState(STOP);
//中断线程池中所有线程
interruptWorkers();
//导出未处理的task
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
//返回当前任务队列中 未处理的任务。
return tasks;
}