ThreadPoolExecutor原理

1 ThreadPoolExecutor介绍

ThreadPoolExecutor是线程池是实现。包含了对线程生命周期的管理。ThreadPoolExecutor的核心参数包括:

    //线程工厂,设置线程名字,方便定位线程
    private volatile ThreadFactory threadFactory;

    //超过最大线程数量之后执行的饱和策略
     1.AbortPolicy:直接抛出异常。     2.CallerRunsPolicy:只用调用者所在线程来运行任务。
     3.DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
     4.DiscardPolicy:不处理,丢弃掉。
     5.也可以根据自定义策略。如先持久化,记录日志或者数据库,后续补偿。
    private volatile RejectedExecutionHandler handler;

    //线程空闲时间,超过这个时间,线程自动退出(默认针对超出corePoolSize的线程)
    private volatile long keepAliveTime;

    //是否回收核心线程
    private volatile boolean allowCoreThreadTimeOut;

    //核心线程数量:
    //小于该数量,执行任务时会创建新的线程
    //默认核心线程是不会回收的,当然也可以设置成可回收
    private volatile int corePoolSize;

    //最大线程数量(包括线程队列里面的线程数量),达到这个线程数的时候会执行饱和策略
    private volatile int maximumPoolSize;

    //线程任务队列
     1.ArrayBlockingQueue:基于数组的有界阻塞队列,此队列有序: FIFO(先进先出)。
     2.LinkedBlockingQueue:基于链表的阻塞队列,此队列有序: 吞吐量通常要高于ArrayBlockingQueue
     3.SynchronousQueue:不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用取出操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue
     4.PriorityBlockingQueue:具有优先级的无界阻塞队列。
    private final BlockingQueue workQueue;

    //默认饱和策略
    private static final RejectedExecutionHandler defaultHandler =
            new ThreadPoolExecutor.AbortPolicy();

注意:

threadFactory一般自定义为线程池创建线程用,通常会为线程创建一个易于理解的名称。

allowCoreThreadTimeOut默认是false,当为true是可以回收空闲的核心线程数。

handler通常可以自定义拒绝策略,可以实现任务持久化,便于后期补偿。

2 ThreadPoolExecutor的状态

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//29
private static final int COUNT_BITS = Integer.SIZE - 3;
// 000-1111111111111111111111111
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
// 111 - 0000000000000000000000000000(十进制: -536, 870, 912) 
private static final int RUNNING    = -1 << COUNT_BITS;
// 000 - 0000000000000000000000000(十进制: 0)
private static final int SHUTDOWN   =  0 << COUNT_BITS;
// 001 - 00000000000000000000000000(十进制: 536,870, 912)
private static final int STOP       =  1 << COUNT_BITS;
// 010 - 00000000000000000000000000.(十进制值: 1, 073, 741, 824)
private static final int TIDYING    =  2 << COUNT_BITS;
// 011 - 000000000000000000000000000(十进制值: 1, 610,612, 736)
private static final int TERMINATED =  3 << COUNT_BITS;

ThreadPoolExecutor通过ctl保存线程池的状态和工作线程数,ctl是一个32位整数,高3位表示线程池状态,低29位表示工作线程数量(workCount),所有工作线程的最大数量是2^29-1。

线程池的状态数值大小一次是RUNNING<SHUTDOWN<STOP<TIDYING<TERMINATED,并且只有RUNNING状态是负数,这样设计的原因是方便状态判断。

线程池状态分为5种RUNNINGSHUTDOWNSTOPTIDYINGTERMINATED

  • RUNNING:(运行)接收新的任务并处理队列里的任务
  • SHUTDOWN:(关闭)不接收新的任务,但是队列中任务会执行
  • STOP:(停止)不接收新的任务,不处理队列中的任务,并终止正在处理的任务
  • TIDYING:(整理)所有任务都被终止的,同时工作线程数量为0
  • TERMINATED:(已终止) terminated()方法执行结束后会进入这一状态,表示线程池已关闭。terminated()方法默认是空方法,可以自定义实现。

下面是这五种状态的转换:

  • RUNNING -> SHUTDOWN:通过调用shutdown()方法实现。

  • (RUNNING or SHUTDOWN) -> STOP:通过调用shutdownNow()方法实现。

  • SHUTDOWN -> TIDYING:task队列和,worker集合为空。

  • STOP -> TIDYING:worker集合为空。

  • TIDYING -> TERMINATED:执行完terminated()方法后。

注意:

ThreadPoolExecutor只提供了shutdown()shutdownNow()两个方法转换状态。其他状态的转变都是隐式装换(tryTerminate()方法中完成)。但是可以通过如下方法查看线程池状态:

public boolean isTerminating() {  
    int c = ctl.get();
    return ! isRunning(c) && runStateLessThan(c, TERMINATED);
}
public boolean isTerminated() {
    return runStateAtLeast(ctl.get(), TERMINATED);
}
public boolean isShutdown() {
    return ! isRunning(ctl.get());
}
2.1 ThreadPoolExecutor获取状态和线程数
    //~CAPACITY: 11100000000000000000000000000001
    //return c & ~CAPACITY:获取c高3位
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    //CAPACITY:00011111111111111111111111111111
    //c & CAPACITY:返回的就是c的低29位
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    //SHUTDOWN是0,小于SHUTDOWN,也就是判断是否是RUNNING
    private static boolean isRunning(int c)     { return c < SHUTDOWN;}
    //通过状态和线程数量组合ctl
    private static int ctlOf(int rs, int wc) { return rs | wc; }
2.2 线程池状态判断
// 判断当前线程池运行状态值是否小于给定值
private static boolean runStateLessThan(int c, int s) {
    return c < s;
}
// 判断当前线程池运行状态值是否大于等于给定值
private static boolean runStateAtLeast(int c, int s) {
    return c >= s;
}

3 ThreadPoolExecutor的运行过程

3.1 execute方法
 public void execute(Runnable command) {
        if (command == null)
            //不能为null
            throw new NullPointerException();
        int c = ctl.get();
        //返回ctl的低29位,判断是否小于核心线程数
        if (workerCountOf(c) < corePoolSize) {
            //创建核心线程执行任务
            if (addWorker(command, true))
                //成功就返回
                return;
            //失败重新获取ctl
            c = ctl.get();
        }
        //走到这,说明大于核心线程数,则判断是否是运行状态,是就往队列中加任务
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            //如果不是RUNNING,就移除当前任务
            if (! isRunning(recheck) && remove(command))
                //失败就执行拒绝策略
                reject(command);
            //判断线程总数量是否为0(有可能线程执行任务报错了,然后就被销毁了)
            else if (workerCountOf(recheck) == 0)
                //创建非核心线程执行任务(注意这里是null)
                addWorker(null, false);
        }
        //走到这,说明不是运行状态或者队列满了,就创建非核心线程执行任务
        else if (!addWorker(command, false))
            //失败就执行拒绝策略
            reject(command);
    }

上述代码的执行流程如下:

注意:

只有在线程池处于RUNNING状态时提交任务的任务才会被执行,否则执行拒绝策略。

3.2 addWorker方法
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            // 运行状态
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            // 分两种情况考虑:
            // 1、如果线程池状态>SHUTDOWN,即(STOP,TIDYING,TERMINATED)中的一个,直接返回false(因为这些条件下要求 清空队列,正在运行的任务也要停止)
            // 2、如果线程池状态=SHUTDOWN & (firstTask!=null || 队列为空)直接返回false, 
            // 换言之,在SHUTDOWN状态下, 想要创建一个firstTask为空的新worker,需要确保队列不为空(队列为空就意味着这个新的worker暂时还没有任务可以执行,所以也没有创建worker的必要, 因为这个worker是用来消化队列中的任务)
            // 大部分情况下,我们需要新创建的worker的firstTask都有初始化任务, 在SHUTDOWN状态下,就不允许在创建worker了,直接返回false
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                // 计算worker的数量
                int wc = workerCountOf(c);
                // 如果worker数量已经超过指定大小,则不允许创建
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                // 尝试cas累加worker的数量,如果成功就跳出最外层循环    
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                // 本次cas失败,表明ctl已经变了,检查线程池状态,如果状态变了就跳到最外层重新执行一次
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
                // 如果到这里了说明是worker的数量改变了导致的cas失败,那就在内层自旋操作 再来一次
            }
        }

        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());

                    // 状态rs < SHUTDOWN表明是RUNNING状态
                    // 如果线程池的状态是SHUTDOWN,那么创建的worker是用来处理队列中的任务,因此需要满足firstTask == null
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        // 如果线程提前start则认为是异常状态
                        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) {
                    // 这里启动worker运行
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                // 如果添加worker失败了,这里需要处理一下
                addWorkerFailed(w);
        }
        return workerStarted;
    }  

当创建新worker时,firstTask为null的含义:

  • 首先需要知道的是worker执行的任务的来源,一是初始化时的firstTask 即当前worker的第一个任务, 二是从队列里取

  • firstTask表示当前worker初始化任务,也就是第一个要执行的任务;如果firstTask=null, 说明此worker只从队列中取任务来执行

  • 所以当创建firstTask为null的worker时,只有队列不为空才有创建的必要,因为目的是去消化队列中的任务

分三种情况来看创建worker:

  • 正常情况下线程池的状态是RUNNING,这个时候只需根据corePoolSize或者maximumPoolSize来判断是否应该创建新的woker

  • 如果是STOP,TIDYING,TERMINATED状态,表明线程池处于清理资源,关闭线程池(清空队列,终止正在运行的任务,清空worker),这个时候不允许创建新的worker

  • SHUTDOWN状态,此状态比较特殊,因为在此状态会继续处理队列中的任务,但是不允许往队列中新增任务,同时正常处理的任务也会继续处理; 此状态下,在firstTask为null并且队列不为空的情况下可以创建新的worker来处理队列中的任务,其他情况是不允许的

3.3 addWorkerFailed方法

当worker启动失败时处理:

    private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
                workers.remove(w);
            // worker计数器减1    
            decrementWorkerCount();
            // 尝试终止线程池
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    } 

4 Worker线程

worker继承AbstractQueuedSynchronizer,实现了非重入锁

  • state=0, 表示锁未被持有
  • state=1, 表示锁被持有
  • state=-1, 初始化的值,防止worker线程在真正运行task之前被中断,

Worker也是一个任务,实现了Runnable接口。

    private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {

        // 每个worker中都会封装一个真正用于处理任务的线程
        final Thread thread;
        // 这个worker初始化的时候分配的首个任务
        Runnable firstTask;
        // 记录当前worker处理完的任务数量
        volatile long completedTasks;

        // 构造方法
        Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            // 使用ThreadFactory创建线程
            // 这里this是当前实现了Runnable接口的Worker对象,也就是说当我调用thread.start()方法时,就会调用worker的入口方法run
            this.thread = getThreadFactory().newThread(this);
        }

        // 基于AQS实现的非重入锁
        protected boolean isHeldExclusively() {
             return getState() != 0;
         }

         // 实际并未使用传入的参数
         // state=0表示可以获取,将state设置为1表示获取成功
         protected boolean tryAcquire(int unused) {
             if (compareAndSetState(0, 1)) {
                 setExclusiveOwnerThread(Thread.currentThread());
                 return true;
             }
             return false;
         }

         // 实际并未使用传入的参数
         // 将state设置为0表示锁释放成功
         protected boolean tryRelease(int unused) {
             setExclusiveOwnerThread(null);
             setState(0);
             return true;
         }

         public void lock()        { acquire(1); }
         public boolean tryLock()  { return tryAcquire(1); }
         public void unlock()      { release(1); }
         public boolean isLocked() { return isHeldExclusively(); }        

        // worker的主要入口逻辑
        public void run() {
            runWorker(this);
        }
}
4.1 runWorker方法
    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        // 和setState(-1); 相对应
        // 这个时候state=0了,也就可以被中断了,(ThreadPoolExecutor.Worker#interruptIfStarted)
        w.unlock(); // allow interrupts
        // 是否有异常产生
        boolean completedAbruptly = true;
        try {
            // task的来源要么是firstTask,要么是队列
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                // 如果线程池是STOP及之后的状态,需要确保它是中断的
                // 如果是STOP之前的状态,就要确保它不能被中断(如果有的话就要清除中断标志,Thread.interrupted会清除中断标志)
                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);
        }
    } 

注意:

Worker有两种方式结束线程执行:

  1. task.run()执行业务方法时抛出异常,或者响应wt.interrupt()中断抛出异常。

  2. getTask()方法返回null,正常退出执行。

线程退出时会执行processWorkerExit()方法,completedAbruptlytrue表示异常退出,false表示正常退出。

Worker线程通过加锁改变state状态来表示线程是否空闲。beforeExecuteafterExecute可以自定义实现扩展。

4.2 getTask方法
    private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            // 线程池状态
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            // 两种情况从队列里面取不到task
            // 1、线程池是STOP状态,这个状态会清空队列,同时停止正在处理的任务,自然,如果是这个状态,直接返回null,表明取不到task
            // 2、线程池是SHUTDOWN状态并且队列为空,因为此状态下 队列里是不会新增任何task,所以在队列为空的情况下,自然也是取不到
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                // worker数量减一
                decrementWorkerCount();
                return null;
            }

            // 计算worker数量
            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            // 通过最大线程数量或者获取task超时 来决定是否要消减此worker
            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                // 1、timed期限的,非核心线程如果空闲时间超过keepAliveTime,就会被清理掉
                // 因此如果这里从阻塞队列里在keepAliveTime时间内都没有取到task,说明处理超时了
                // 2、没有timed限制的,take阻塞的取task
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

此方法有两处返回null,用于退出线程。

第一处:

  • 当线程池处于STOP及之后的状态

  • 线程池处于SHUTDOWN状态并且任务队列没有任务。

第二处:

  • 线程数超过最大线程数

  • 线程获取任务超时

注意:

此方法是用于清除空闲线程,通过超时获取任务队列来清除非核心线程,通过设置allowCoreThreadTimeOuttrue也可以清除空闲的核心线程。

4.3 processWorkerExit方法

对worker执行结束之后,清理掉当前worker之后考虑是否采取用新的worker来替换

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        //异常结束workerCount减一,正常结束在getTask已经
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 当前worker完成的task数量累加
            completedTaskCount += w.completedTasks;
            // 从woker Set中移除当前worker
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        // 每次worker结束后都要尝试终止线程池,说不定某个时刻worker都被清理了并且达到了线程池终止的条件
        // 就可以从这里结束
        tryTerminate();

        int c = ctl.get();
        // 如果线程池状态小于STOP
        if (runStateLessThan(c, STOP)) {
            // 如果不是异常
            // 如果用户任务发生了异常,尝试替换worker
            // 或者核心线程数量小于corePoolSize,尝试添加worker
            // 或者队列非空,但是已经没有worker了,尝试添加worker
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }

            // 这里新添加worker,没有初始化的firstTask, 这里worker处理的任务来自于队列
            addWorker(null, false);
        }
    }   

流程说明:

  1. 从worker set中移除当前worker

  2. 尝试终止线程池

  3. 如果线程池状态还未达到STOP,则可以根据以下情况添加新的worker

    • 用户task抛出了异常(也就是completedAbruptly=true)

    • 运行的线程数已经小于核心线程数

    • 运行的线程数为0,但是队列中的任务不为空

5 线程池关闭

5.1 shutDown方法
public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // 如果有security管理,需要确保有权限去shutdown线程池
            checkShutdownAccess();
            // 设置线程池状态为SHUTDOWN
            advanceRunState(SHUTDOWN);
            // 中断所有空闲线程
            interruptIdleWorkers();
            // 为ScheduledThreadPoolExecutor提供的钩子方法
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }

        // 尝试终止线程池
        tryTerminate();
    }
private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                // 空闲状态下worker的锁资源肯定是可以直接获取到的,因此根据此便可以判别线程是否空闲
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        // 打上中断标志
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    } 

流程说明

  • 先将线程池的状态改为SHUTDOWN
  • 尝试中断所有空闲线程(通过线程是否可加锁判断是否空闲)
  • 尝试终止线程池
5.2 shutDownNow方法
 // 返回队列中未执行的task列表
    public List shutdownNow() {
        List tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            // 将线池的状态设置为STOP
            advanceRunState(STOP);
            // 中断所有worker
            interruptWorkers();
            // 清空队列
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }

        // 尝试终止线程池
        // 虽然线程池状态已经改成了STOP状态,但还需要workers被清空之后才会真正变成TERMINATED状态
        // 所以这里不一定会成功, runWorker方法中处理worker退出时会触发tryTerminate
        tryTerminate();
        return tasks;
    }

    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }

        // Worker内部方法
        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }        

流程说明:

  • 先将线程池的状态改为STOP

  • 尝试中断所有线程

  • 清空任务队列

  • 尝试终止线程池

5.3 tryTerminate方法

尝试关闭线程池

final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            // 如果线程池是RUNNING状态的
            // 如果线程池是TIDYING、TERMINATED状态的不管(基本已经处于关闭状态了)
            // 如果线程池是SHUTDOWN状态并且队列中还有task(SHUTDOWN态下还是会处理现有的task)
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;

            // 到这里就说明需要开始线程池终止操作  
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // 操作1:设置线程池状态为TIDYING,worker数量为0
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        // terminated钩子方法
                        terminated();
                    } finally {
                        // 操作1设置后,又处理了terminated方法,那么就可以把线程池置为TERMINATED状态了(线程池已完全关闭)
                        ctl.set(ctlOf(TERMINATED, 0));
                        // 通知在termination条件上等待的操作
                        // 比如awaitTermination方法的等待操作,这里唤醒后,可能会提前结束等到操作
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

当线程池处于以下状态不需要关闭:

  • 如果线程池是RUNNING状态的

  • 如果线程池是SHUTDOWN状态并且队列中还有task(SHUTDOWN状态下还是会处理现有的task)

ThreadPoolExecutor线程池源码分析_持之以恒-CSDN博客

你可能感兴趣的:(ThreadPoolExecutor原理)