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;
}

  

 
 
 
 
 
 
 
 
 
 
posted on 2023-06-29 13:15  路飞_lufei  阅读(12)  评论(0编辑  收藏  举报