线程池addWorker执行流程(添加工作线程)

发布时间 2023-07-10 10:08:12作者: 啥123
  1 //添加工作线程
  2 private boolean addWorker(Runnable firstTask, boolean core) {
  3 //    对线程池状态的判断以及对工作线程数量的判断
  4 //    外层for循环的标识
  5         retry:
  6         for (;;) {
  7 //            获取ctl值
  8             int c = ctl.get();
  9 //            拿到线程池的状态
 10             int rs = runStateOf(c);
 11 
 12             // 如果当前线程状态不是RUNNING,再次做后续判断,查看当前任务是否可以不处理
 13             if (rs >= SHUTDOWN &&
 14 //                    线程池状态为SHUTDOWN,并且任务为空,并且工作队列不为空
 15 //                    如果同时满足了这三个要求,那就是要处理工作队列当前中的任务
 16                     ! (rs == SHUTDOWN &&
 17                             firstTask == null &&
 18                             ! workQueue.isEmpty()))
 19 //                只要不是RUNNING状态,不处理新任务
 20 //                如果是SHUTDOWN状态,并且满足了之前addWorker(null,false),并且工作队列有任务时,需要创建线程
 21                 return false;
 22 
 23             for (;;) {
 24 //                获取当前工作线程数
 25                 int wc = workerCountOf(c);
 26 //                判断工作线程是否大于最大值
 27                 if (wc >= CAPACITY ||
 28 //                        如果是核心线程,是否大于设置的corePoolSize
 29 //                        如果是非核心线程,是否大于maximumPoolSize
 30                         wc >= (core ? corePoolSize : maximumPoolSize))
 31 //                    当前工作线程已经达到最大值
 32                     return false;
 33 //                以CAS对工作线程数+1,如果成功,直接跳出外层for循环
 34                 if (compareAndIncrementWorkerCount(c))
 35 //                    跳出外层for循环
 36                     break retry;
 37 //                重新获取ctl
 38                 c = ctl.get();  // Re-read ctl
 39 //                基于新获取的ctl拿到线程池状态,判断和之前的rs状态是否一致
 40                 if (runStateOf(c) != rs)
 41 //                    说明并发操作导致线程池状态变化,需要重新判断状态
 42                     continue retry;
 43                 // else CAS failed due to workerCount change; retry inner loop
 44             }
 45         }
 46 
 47 //        添加工作线程并启动工作线程
 48 //    工作线程是否启动
 49         boolean workerStarted = false;
 50 //        工作线程是否添加
 51         boolean workerAdded = false;
 52 //        Worker就是工作线程
 53         ThreadPoolExecutor.Worker w = null;
 54         try {
 55 //            new Worker构建工作线程,将任务扔到了Worker中
 56             w = new ThreadPoolExecutor.Worker(firstTask);
 57 //            拿到了Worker中绑定的Thread线程
 58             final Thread t = w.thread;
 59             if (t != null) {
 60 //                加锁
 61                 final ReentrantLock mainLock = this.mainLock;
 62                 mainLock.lock();
 63                 try {
 64 //                   重新获取ctl,拿到线程池的状态
 65                     int rs = runStateOf(ctl.get());
 66 //                   如果满足线程池状态为RUNNING,就添加工作线程
 67                     if (rs < SHUTDOWN ||
 68 //                            如果线程池状态为SHUTDOWN并且传入的任务为null
 69                             (rs == SHUTDOWN && firstTask == null)) {
 70 //                        开始添加工作线程
 71 //                        判断当前线程是否 处于run状态(健壮性判断)
 72                         if (t.isAlive()) // precheck that t is startable
 73                             throw new IllegalThreadStateException();
 74 //                        将构建好的worker对象添加到worklers
 75                         workers.add(w);
 76 //                        获取工作线程个数
 77                         int s = workers.size();
 78 //                        记录工作线程最大值,如果现在的工作线程数大于历史最大值
 79                         if (s > largestPoolSize)
 80                             largestPoolSize = s;
 81 //                        将工作线程添加的标识设置为true
 82                         workerAdded = true;
 83                     }
 84                 } finally {
 85 //                    释放锁
 86                     mainLock.unlock();
 87                 }
 88 //              只要添加工作线程成功,启动线程
 89                 if (workerAdded) {
 90                     t.start();
 91 //                    将工作线程启动的标识设置为true
 92                     workerStarted = true;
 93                 }
 94             }
 95         } finally {
 96             if (! workerStarted)
 97 //                如果启动工作线程失败,做的补救操作
 98 //                判断之前创建工作线程是否成功,如果成功,将workers中当前工作线程移除
 99 //                将工作线程数减一
100 //                尝试将线程池状态变为TIDYING
101                 addWorkerFailed(w);
102         }
103         return workerStarted;
104     }