了解下JUC的线程池学习八(processWorkerExit方法源码分析)

1.介绍

   processWorkerExit()方法是为将要终结的Worker做一次清理和数据记录工作

 (因为processWorkerExit()方法也包裹在runWorker()方法finally代码块中,

   其实工作线程在执行完processWorkerExit()方法才算真正的终结)。

 

2.源码

   private void processWorkerExit(Worker w, boolean completedAbruptly) {
         // 因为抛出用户异常导致线程终结,直接使工作线程数减1即可
         // 如果没有任何异常抛出的情况下是通过getTask()返回null引导线程 

         //正常跳出runWorker()方法的while死循环从而正常终结,这种情况下,在getTask()中已经把线程数减1
         if (completedAbruptly)// If abrupt, then workerCount wasn't adjusted

                  decrementWorkerCount();

         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
              // 全局的已完成任务记录数加上此将要终结的Worker中的已完成任务数
              completedTaskCount += w.completedTasks;
              // 工作线程集合中移除此将要终结的Worker
              workers.remove(w);
         } finally {
             mainLock.unlock();
         }
    
        // 见下一小节分析,用于根据当前线程池的状态判断是否需要进行线程池terminate处理
        tryTerminate();

        int c = ctl.get();
        // 如果线程池的状态小于STOP,也就是处于RUNNING或者SHUTDOWN状态的前提下:
        // 1.如果线程不是由于抛出用户异常终结,如果允许核心线程超时,则保持线程池中至少存在一个工作线程
        // 2.如果线程由于抛出用户异常终结,或者当前工作线程数,那么直接添加一个新的非核心线程
        if (runStateLessThan(c, STOP)) {
             if (!completedAbruptly) {
                // 如果允许核心线程超时,最小值为0,否则为corePoolSize
               int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
               // 如果最小值为0,同时任务队列不空,则更新最小值为1
               if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                    // 工作线程数大于等于最小值,直接返回不新增非核心线程
                   if (workerCountOf(c) >= min)
                     return; // replacement not needed
         }
         addWorker(null, false);
       }
  }

 

总结:代码的后面部分区域,会判断线程池的状态,

           如果线程池是RUNNING或者SHUTDOWN状态的前提下,

           如果当前的工作线程由于抛出用户异常被终结,那么会新创建一个非核心线程。

          如果当前的工作线程并不是抛出用户异常被终结(正常情况下的终结),那么会这样处理:

            第一种:allowCoreThreadTimeOut为true,也就是允许核心线程超时的前提下,

                         如果任务队列空,则会通过创建一个非核心线程保持线程池中至少有一个工作线程。

            第二种:allowCoreThreadTimeOut为false,如果工作线程总数大于corePoolSize则直接返回,

                         否则创建一个非核心线程,也就是会趋向于保持线程池中的工作线程数量趋向于corePoolSize

         processWorkerExit()执行完毕之后,意味着该工作线程的生命周期已经完结。

       

学习来源:https://www.cnblogs.com/throwable/p/13574306.html 

posted @ 2020-09-02 17:14  小窝蜗  阅读(1140)  评论(1)    收藏  举报