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();
//获取当前worker的任务(任务可能为空20) Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { while (task != null || (task = getTask()) != null) { w.lock();
//当前if判断就是判断当前线程池是否处于stop状态 if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()) wt.interrupt(); try {
/执行任务前置 执行一些预先任务 当前ThreadPoolExecutor空实现
//我们可以在自定中处理一些前置操作 beforeExecute(wt, task); Throwable thrown = null; try {
//执行传进来的任务或者队列第一个的任务的run方法 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(); //设置线程池状态为SHUTDOWN
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; }