ThreadPoolExecutor————一文解决ThreadPoolExecutor源码

源码解读的注释都在代码中,有些重复的代码没有注释,如若有哪些地方我理解错了欢迎评论区留言或者私信我指正,成长的路上相互学习共同进步。
以下是ThreadPoolExecutor的所有源码,建议按照以下的顺序看
1、先了解ThreadPoolExecutor的常量
2、了解Worker内部类的结构
3、execute()方法
4、addWorker()方法
5、runWorker()方法
6、completedAbruptly()方法
7、processWorkerExit()方法
8、getTask()方法
9、shutdown()方法
10、shutdownnow()方法
11、tryTerminal()方法

除了这些方法,在阅读过程中涉及的其他方法自行移步读,基本都有相应解读

package Executor;

/**
 * @author hejs
 * @version 1.0
 * @createDate 2022年03月02日 09:00
 * @since JDK1.8
 */
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
 *   private boolean isPaused;
 *   private ReentrantLock pauseLock = new ReentrantLock();
 *   private Condition unpaused = pauseLock.newCondition();
 *
 *   public PausableThreadPoolExecutor(...) { super(...); }
 *
 *   protected void beforeExecute(Thread t, Runnable r) {
 *     super.beforeExecute(t, r);
 *     pauseLock.lock();
 *     try {
 *       while (isPaused) unpaused.await();
 *     } catch (InterruptedException ie) {
 *       t.interrupt();
 *     } finally {
 *       pauseLock.unlock();
 *     }
 *   }
 *
 *   public void pause() {
 *     pauseLock.lock();
 *     try {
 *       isPaused = true;
 *     } finally {
 *       pauseLock.unlock();
 *     }
 *   }
 *
 *   public void resume() {
 *     pauseLock.lock();
 *     try {
 *       isPaused = false;
 *       unpaused.signalAll();
 *     } finally {
 *       pauseLock.unlock();
 *     }
 *   }
 * }}</pre>
 *
 * @since 1.5
 * @author Doug Lea
 */
public class ThreadPoolExecutor extends AbstractExecutorService {
    //用来标记线程池状态(高3位),线程个数(低29位)
    //默认是RUNNING状态,线程个数为0
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

    //线程个数掩码位数,并不是所有平台int类型是32位,所以准确说是具体平台下Integer的二进制位数-3后的剩余位数才是线程的个数,
    private static final int COUNT_BITS = Integer.SIZE - 3;
    // CAPACITY 工作线程最大数量
    //(底29位):00011111111111111111111111111111
    private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;

    //线程最大个数(低29位)00011111111111111111111111111111
    //(高3位):11100000000000000000000000000000
    //RUNNING:接受新任务并且处理阻塞队列里的任务;
    private static final int RUNNING    = -1 << COUNT_BITS;

    //(高3位):00000000000000000000000000000000
    //SHUTDOWN:拒绝新任务但是处理阻塞队列里的任务;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;

    //(高3位):00100000000000000000000000000000
    //STOP:拒绝新任务并且抛弃阻塞队列里的任务,同时会中断正在处理的任务;
    private static final int STOP       =  1 << COUNT_BITS;

    //(高3位):01000000000000000000000000000000
    //TIDYING:所有任务都执行完(包含阻塞队列里面任务)当前线程池活动线程为 0,将要调用 terminated 方法;
    private static final int TIDYING    =  2 << COUNT_BITS;

    //(高3位):01100000000000000000000000000000
    //TERMINATED:终止状态,terminated方法调用完成以后的状态。
    private static final int TERMINATED =  3 << COUNT_BITS;

    // 获取高三位 运行状态
    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~COUNT_MASK; }
    //获取低29位 工作线程个数
    private static int workerCountOf(int c)  { return c & COUNT_MASK; }
    //计算ctl新值,线程状态 与 线程个数
    private static int ctlOf(int rs, int wc) { return rs | wc; }


    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }

    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }

    private void decrementWorkerCount() {
        ctl.addAndGet(-1);
    }

    private final BlockingQueue<Runnable> workQueue;
    //独占锁,用于控制新增 Worker 线程时候的原子性
    private final ReentrantLock mainLock = new ReentrantLock();

    private final HashSet<ThreadPoolExecutor.Worker> workers = new HashSet<>();
    //是mainLock锁对应的条件队列,在线程调用 awaitTermination 时候用来存放阻塞的线程
    private final Condition termination = mainLock.newCondition();

    private int largestPoolSize;

    private long completedTaskCount;


    private volatile ThreadFactory threadFactory;

    private volatile RejectedExecutionHandler handler;

    private volatile long keepAliveTime;
    private volatile boolean allowCoreThreadTimeOut;

    private volatile int corePoolSize;

    private volatile int maximumPoolSize;

    private static final RejectedExecutionHandler defaultHandler =
            new ThreadPoolExecutor.AbortPolicy();

    private static final RuntimePermission shutdownPerm =
            new RuntimePermission("modifyThread");

    private final class Worker extends AbstractQueuedSynchronizer implements Runnable
    {
        private static final long serialVersionUID = 6138294804551838833L;

        /** Thread this worker is running in.  Null if factory fails. */
        final Thread thread;
        /** Initial task to run.  Possibly null. */
        Runnable firstTask;
        /** Per-thread task counter */
        volatile long completedTasks;

        // TODO: switch to AbstractQueuedLongSynchronizer and move
        // completedTasks into the lock word.

        /**
         * 使用线程工厂创建工作线程,发放任务给工作线程
         * @param firstTask
         */
        Worker(Runnable firstTask) {
            //设置工作线程状态为-1,在真正执行任务前禁止中断
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker. */
        @Override
        public void run() {
            runWorker(this);
        }

        // Lock methods
        //
        // The value 0 represents the unlocked state.
        // The value 1 represents the locked state.

        @Override
        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        @Override
        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        /**
         * 这里的加锁解锁的方法利用AQS中的state变量,-1表示禁止打断还未启动的线程,0表示没有线程持有锁  1,表示有线程持有锁
         * 用于标记工作线程的空闲状态(空闲线程没加锁,加了锁的便不是空闲线程)
         */
        public void lock()        { acquire(1); }
        public boolean tryLock()  { return tryAcquire(1); }
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }

        /**
         * 打断已经启动且没有被打断过的工作线程,打断过的线程不必再打断了(再打断就是多此一举)
         * //被打断过的会在getTask那儿抛中断异常
         */
        void interruptIfStarted() {
            Thread t;
            //运行状态大于0,表示还有启动的任务,便打断
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }

    /**
     *修改线程池运行状态
     * @param targetState
     */
    private void advanceRunState(int targetState) {
        // assert targetState == SHUTDOWN || targetState == STOP;
        for (;;) {
            int c = ctl.get();
            //当前线程池状态已经是目标状态以上了,那么没必要进行修改,否者进行修改成功后返回,
            if (runStateAtLeast(c, targetState) ||
                    ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

    /**
     * 尝试终止线程池
     * 如果线程池还有多个线程或者已经进入整理,或者
     * 停止且任务队列为空,返回,说明有线程在做终止操作了
     * 不需要自己在处理了,如果还有多个工作线程,减少一个空闲线程
     * 如果线程池的工作线程为0了,
     * 那么进入该方法的就是线程池唯一的线程,必须自己终止线程
     */
    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            //如果线程池处于running状态,线程池是正常的                                                                      无需处理,返回,
            //如果线程池处于整理状态 说明 已经有其它线程 在执行 TIDYING -> TERMINATED状态了                                   无需处理,返回
            //如果线程池小于停止状态 但是 任务队列为空  这是SHUTDOWN的特殊情况,直接回去。得等队列中的任务处理完毕后,再转化状态。 无需处理,返回
            if (isRunning(c) ||
                    runStateAtLeast(c, TIDYING) ||
                    (runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
                return;
            //如果线程池中工作线程数量不为0,释放一个空闲工作线程
            //其实就是通过中断信号,唤醒阻塞的线程(getTask()阻塞的)
            //这里为什么只释放一个呢?
            //因为tryTerminate方法多个方法都在调用,工作线程任务执行完后processWorkerExit里面也会调用,
            // 所以每次执行完任务都会调用,所以每次都中断其中一个线程。
            if (workerCountOf(c) != 0) { // Eligible to terminate
                //释放一个空闲工作线程
                interruptIdleWorkers(ONLY_ONE);
                return;
            }
            //到这里说明是这是线程池中最后一个线程了,所以执行终止操作
            //线程池最后一个线程执行终止线程池
            final ReentrantLock mainLock = this.mainLock;
            //获取线程池全局锁
            mainLock.lock();
            try {
                //cas将运行状态设置为整理状态,工作线程为0
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        //钩子函数,按需重写,这里为空方法
                        terminated();
                    } finally {
                        //设置运行状态为终止状态
                        ctl.set(ctlOf(TERMINATED, 0));
                        //唤醒调用 awaitTermination() 方法的线程。
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

    private void checkShutdownAccess() {
        // assert mainLock.isHeldByCurrentThread();
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(shutdownPerm);
            for (ThreadPoolExecutor.Worker w : workers)
                security.checkAccess(w.thread);
        }
    }

    /**
     * 打断所有已经启动的工作线程
     */
    private void interruptWorkers() {
        // assert mainLock.isHeldByCurrentThread();
        for (ThreadPoolExecutor.Worker w : workers)
            w.interruptIfStarted();
    }

    /**
     * 释放空闲线程
     * @param onlyOne
     */
    private void interruptIdleWorkers(boolean onlyOne) {
        //加锁,防止多个线程导致问题,shutdown虽然也加了锁再调用这个方法,
        // 但是还有其他方法也调这个方法呢
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //如果不是要求释放一个空闲工作线程的话,将线程容器中的空闲线程释放掉
            for (ThreadPoolExecutor.Worker w : workers) {
                Thread t = w.thread;
                //如果线程被中断过,不必再中断了,进入下一循环
                // 如果线程没有被打断过,
                // 并且获取到了锁(空闲线程在获取任务队列中的任务时是阻塞在get方法上,
                // 取到了任务在加锁执行,所以在这里获取到了锁,说明是空闲线程,也就是阻塞在任务队列取任务的线程)
                if (!t.isInterrupted() && w.tryLock()) {
                    //是空闲线程则设置打断标志位
                    try {
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        //加锁后记得解锁
                        w.unlock();
                    }
                }
                //如果只要求释放一个线程,那么释放一个工作线程后结束循环
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 没带参数,默认打断所有空闲线程
     */
    private void interruptIdleWorkers() {
        interruptIdleWorkers(false);
    }

    private static final boolean ONLY_ONE = true;


    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }
    void onShutdown() {
    }

    /**
     * 取出任务队列中的所有任务
     * @return
     */
    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<>();
        //任务队列中还有任务,逐个取出放到容器中返回,取出就是拿出来,阻塞队列拿一个少一个
        q.drainTo(taskList);
        // 如果执行完drainTo后,q还不是空的
        // 是因为,阻塞队列是延迟队列来的,延迟队列的话是不具备删除功能,需要手动取出
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }

    /**
     * 添加工作线程执行任务
     * 调用该方法的情况
     * 1、核心线程还未满,添加核心线程执行任务
     * 2、核心线程满了,任务添加到阻塞队列添加成功了,但核心线程都超时了,
     * 导致线程池中线程数为0,添加一个补尝线程执行任务;(前提是开启了核心线程超时销毁)
     * 3、核心线程和阻塞队列都满了。则开启非核心线程来执行任务
     * @param firstTask
     * @param core
     * @return
     */
    private boolean addWorker(Runnable firstTask, boolean core) {
        //此嵌套死循环执行成功的话只做了运行状态加1,即工作线程数加1,而非添加了工作线程
        retry:
        for (int c = ctl.get();;) {
            // Check if queue empty only if necessary.
            /**
             *  RUNNING:接受新任务 并且 处理 阻塞队列里的任务;
             *  SHUTDOWN:拒绝新任务 但是 处理 阻塞队列里的任务;
             *  STOP:拒绝新任务 并且 抛弃 阻塞队列里的任务,同时会 中断 正在处理的任务;
             *  TIDYING:所有任务都执行完(包含阻塞队列里面任务)当前线程池活动线程为 0,将要调用 terminated 方法;
             *  TERMINATED:终止状态,terminated方法调用完成以后的状态。
             */
            if ( //线程池状态不为running状态,即为SHUTDOWN、STOP、TIDYING、TERMINATED中的一种
                 //该状态下要求不再接收新任务,如果后面判断也是true 则返回false execut()方法不做处理或者执行拒绝策略
                    runStateAtLeast(c, SHUTDOWN) &&
                    //线程池状态为STOP、TIDYING、TERMINATED中的一种,这些状态下不再处理任务,即使正在处理的线程也得中断
                    (runStateAtLeast(c, STOP)
                    //如果线程池状态为SHUTDOWN,且有提交的任务。则返回false
                    // 这里如果提交的任务为空,则是补充线程
                    || firstTask != null
                    //如果线程池状态为SHUTDOWN,且提交的任务为空(补充线程),阻塞队列为空,则返回false
                    || workQueue.isEmpty())
            )
                //返回false,execut()方法不做处理或者执行拒绝策略
                return false;
            //执行到这儿,有2种情况1:线程池处于running状态(接收新任务)
            //2、线程池处于SHUTDOWN状态、提交的空任务(补充线程)
            // 且阻塞队列不为空(即处于SHUTDOWN状态,还需继续执行阻塞队列的任务)
            for (;;) {
                //检查工作线程数
                //如果加的是核心线程检查是否大于核心线程数
                //如果加的是非核心线程,那么检查是否大于最大线程数
                if (workerCountOf(c)
                        >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
                    return false;
                //到这儿说明可以加工作线程
                //多线程下CAS尝试将工作线程数(运行状态)加1
                if (compareAndIncrementWorkerCount(c))
                    //添加成功,结束外循环
                    break retry;
                //到这儿说明有其他线程更改了运行状态(线程数量或运行状态),工作线程加1失败
                //重新获取运行状态快照
                c = ctl.get();  // Re-read ctl
                //判断运行状态是不是running状态了,如果已经不是running状态了就回到外循环
                if (runStateAtLeast(c, SHUTDOWN))
                    continue retry;
                // 到这儿说明是线程数量发生了改变,再次执行内循环更改运行状态加1
            }
        }
        //运行到这儿,说明ctl(运行状态)的工作线程数已成功加1了
        //下面便是完成创建线程执行提交的任务
        boolean workerStarted = false;//worker是否开始执行,也就是是否执行:t.start();
        boolean workerAdded = false;// worker是否被加入到工作线程队列(HashSet)中
        ThreadPoolExecutor.Worker w = null;
        try {
            //创建工作线程,并将任务发放给工作线程(只是创建,还没让其启动执行),work有个state为-1,即工作线程还未启动
            w = new ThreadPoolExecutor.Worker(firstTask);
            final Thread t = w.thread;
            //工作线程创建成功,加独占锁。保证添加到工作线程到HashSet队列中是线程安全的操作
            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 c = ctl.get();
                    //检查线程池运行状态,
                    if (isRunning(c) ||
                            //如果线程池处于SHUTDOWN状态并且提交的工作线程是空的(即是补充线程)那么添加工作线程
                            (runStateLessThan(c, STOP) && 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();
                    workerStarted = true;
                }
            }
        } finally {
            //添加任务的过程中失败了或者添加成功了,但是执行任务的线程启动失败了,执行失败的方法
            if (! workerStarted)
                addWorkerFailed(w);
        }
        //返回添加成功或失败
        return workerStarted;
    }

    /**
     * 添加工作线程失败,从工作线程容器中移除,并减线程数量
     * @param w
     */
    private void addWorkerFailed(ThreadPoolExecutor.Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
                //从工作线程容器中移除
                workers.remove(w);
            //ctl线程数减1
            decrementWorkerCount();
            //尝试终止线程池
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 将运行结束后的工作线程移出HashSet队列,再补充一个空线程进去
     * @param w
     * @param completedAbruptly
     */
    private void processWorkerExit(ThreadPoolExecutor.Worker w, boolean completedAbruptly) {
        //如果是任务执行过程中发生了错误,cas减少工作线程数
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();
        //加锁,保证工作线程移出队列的安全性
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            //将工作线程移出HashSet队列
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        //如果线程池是RUNNING或者SHUTDOWN状态
        if (runStateLessThan(c, STOP)) {
            //如果任务顺利完成(completedAbruptly=false)
            if (!completedAbruptly) {
                //判断是否设置了允许核心线程超时
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                //如果设置了核心线程允许超时,且阻塞队列还有任务
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                //工作线程保证至少还有一个来执行任务,有就返回,否者继续往下执行,添加一个工作线程(补偿)
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            //总结上面if判断:如果线程池是RUNNING或者SHUTDOWN状态,且任务队列不是空,那么至少保证线程池中有一个线程在执行任务
            addWorker(null, false);
        }
    }

    /**
     * 从阻塞队列中获取任务
     * 如果工作线程没设置超时,那么会一直阻塞在获取任务这儿
     * 如果设置了,一旦超时,那么便会使工作线程结束其生命周期
     * @return
     */
    private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();

            //如果线程池状态不能再接收任务了,并且  (线程池状态也不能执行任务了或者阻塞队列已经空了)
            //总结:1、如果线程状态大于STOP,即不再执行任务,工作线程不必在阻塞在获取任务这儿了
            //      2、如果线程池状态为SHUTDOWN并且线程池为空,工作线程也不必再阻塞在获取任务这儿了,因为也不会接收新任务了
            if (runStateAtLeast(c, SHUTDOWN)
                    && (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
                //工作线程减1并返回空
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // 是否允许核心线程超时,允许,返回true,线程活跃数超过核心线程数也返回true
            //总结:1、活跃线程数大于核心线程数(大于1),减少工作线程数到核心线程的个数
            //      2、活跃线程数不大于核心线程数了
            //          2.1、设置了允许核心线程数超时,并且获取任务超时了
            //          工作队列一直为空 那么减少工作线程数直至为0,不为空,就直至只有一个工作线程
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
            //如果活跃线程数大于核心线程数,或者允许超时且已经超时
            if ((wc > maximumPoolSize || (timed && timedOut))
                    //活跃线程数大于1或者阻塞队列为空
                    && (wc > 1 || workQueue.isEmpty())) {
                //减少工作线程数
                if (compareAndDecrementWorkerCount(c))
                    return null;
                //减少失败再次循环减
                continue;
            }

            //timed是true,执行workQueue.poll()也就是设置获取任务的超时时间,
            // 到时间后还没获取到任务的话则会timeOut=true。
            try {
                Runnable r = timed ?
                        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                        //timed为false,那么工作线程会一直阻塞在这儿,直到获取到一个任务
                        workQueue.take();
                //获取到任务返回
                if (r != null)
                    return r;
                //timeOut=true的话,getTask会让其跳出循环,线程生命周期便会结束。
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

    /**
     * 工作线程执行任务
     * @param w
     */
    final void runWorker(ThreadPoolExecutor.Worker w) {
        Thread wt = Thread.currentThread();
        //获取添加工作线程时分配的任务,如果task为空则工作线程已经执行了添加工作线程时的任务,再次执行的话就得从任务队列中取了
        Runnable task = w.firstTask;
        w.firstTask = null;
        // 之前设置线程还未启动的时候state为-1,禁止打断,
        // 这里恢复为0,表示运行过程中可以打断
        w.unlock();
        boolean completedAbruptly = true;
        try {
            //任务不为空,便执行任务(注意:这里是有任务才加锁执行)
            //否者从阻塞队列中取任务,如果阻塞队列没任务,那么一直阻塞在这儿
            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(执行了shutdownNow),
                // 并且当前线程没有被中断过的(!wt.isInterrupted()),则让线程中断,
                // STOP状态要求运行的线程也会中断
                if ((runStateAtLeast(ctl.get(), STOP) ||
                        (Thread.interrupted() &&
                                runStateAtLeast(ctl.get(), STOP))) &&
                        !wt.isInterrupted())
                    wt.interrupt();
                //如果线程池处于还能运行任务的状态(running、shutdown)那么执行任务
                try {
                    /**
                     * 线程任务开始执行前做一些处理,可以自定义实现方法。模板方法。
                     * 需要注意的地方是该方法只被try finally包起来了,没有catch,
                     * 也就是说异常会被吞,即使报错,如果用户不做catch捕获的话,
                     * 也不会影响线程下面的工作
                     */
                    beforeExecute(wt, task);
                    try {
                        task.run();
                        /**
                         * 线程任务开始执行后做一些处理,可以自定义实现方法。模板方法。
                         * 需要注意的地方是该方法只被try finally包起来了,没有catch,
                         * 也就是说异常会被吞,即使报错,如果用户不做catch捕获的话,
                         * 也不会影响线程下面的工作
                         */
                        afterExecute(task, null);
                    } catch (Throwable ex) {
                        /**
                         * 线程任务开始执行后做一些处理,可以自定义实现方法。模板方法。
                         * 需要注意的地方是该方法只被try finally包起来了,没有catch,
                         * 也就是说异常会被吞,即使报错,如果用户不做catch捕获的话,
                         * 也不会影响线程下面的工作
                         */
                        afterExecute(task, ex);
                        throw ex;
                    }
                } finally {
                    //执行完后将任务置空,回到循环等待从阻塞队列中获取任务
                    task = null;
                    //执行完后,完成任务加1
                    w.completedTasks++;
                    //解锁,用于判断线程是否是空闲,
                    w.unlock();
                }
            }
            //执行任务正常才置为false,如果发生异常则是默认的true,这里发生的异常基本上都是重写那两个模板方法中出现的
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                Executors.defaultThreadFactory(), defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                threadFactory, defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                Executors.defaultThreadFactory(), handler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
                maximumPoolSize <= 0 ||
                maximumPoolSize < corePoolSize ||
                keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

    /**
     * 根据线程池状态将任务 添加进阻塞队列
     * 还是 创建线程执行 还是 执行拒绝策略
     * @param command
     */
    @Override
    public void execute(Runnable command) {
        //如果任务为空,抛出异常
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        //如果线程池的工作线程小于核心线程 就新建工作线程执行任务
        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);
            //到这儿说明线程池是running状态或者移除任务失败,并且任务添加任务队列成功
            //检查工作线程数是不是为0,为0,就添加一个工作线程进行补偿
            //(为0是因为核心线程允许超时销毁,此时刚好线程都销毁了)
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //到这儿说明核心线程数满了,任务队列也满了,
        // 如果还有任务提交就尝试添加非核心线程执行任务
        else if (!addWorker(command, false))
            //尝试添加非核心线程执行任务失败,说明已经到达最大线程数及任务队列已经满了,则执行拒绝策略
            reject(command);
    }

    /**
     * 关闭线程池
     * 提供有钩子函数onShutdown(),shutdownnow()方法没有
     * shutdown执行会让在任务队列中的任务继续执行完
     * shutdownnow不会,而是返回没有执行的任务回来
     */
    @Override
    public void shutdown() {
        //加锁防止多个线程同时执行
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //检查关闭线程池权限
            checkShutdownAccess();
            //修改线程池状态为关闭状态--该状态还可以继续处理阻塞队列中的任务
            advanceRunState(SHUTDOWN);
            //打断空闲线程
            interruptIdleWorkers();
            //钩子函数,模板方法,按需重写
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        //尝试终止线程池
        tryTerminate();
    }

    /**
     * 立即停止线程池,并返回阻塞队列中的任务
     * @return
     */
    @Override
    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        //加锁,防止多个线程同时执行
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            //设置线程池状态为停止状态--该状态既不能接收新任务,也不执行阻塞队列中的任务
            advanceRunState(STOP);
            //打断所有的工作线程
            interruptWorkers();
            //取出阻塞队列中的任务
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        //终止线程池
        tryTerminate();
        return tasks;
    }

    @Override
    public boolean isShutdown() {
        return runStateAtLeast(ctl.get(), SHUTDOWN);
    }

    /** Used by ScheduledThreadPoolExecutor. */
    boolean isStopped() {
        return runStateAtLeast(ctl.get(), STOP);
    }

    public boolean isTerminating() {
        int c = ctl.get();
        return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);
    }

    /**
     * 设置线程池状态为终止状态
     * @return
     */
    @Override
    public boolean isTerminated() {
        return runStateAtLeast(ctl.get(), TERMINATED);
    }

    /**
     * 工作线程等待线程池终止
     * @param timeout
     * @param unit
     * @return
     * @throws InterruptedException
     */
    @Override
    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //线程池状态大于等于TERMINATED了,也就是线程池已经terminated了,则直接返回true
            while (runStateLessThan(ctl.get(), TERMINATED)) {
                // 如果达到超时时间,已经超时,则返回false
                if (nanos <= 0L)
                    return false;
                // 重置距离超时时间的剩余时长
                nanos = termination.awaitNanos(nanos);
            }
            return true;
        } finally {
            mainLock.unlock();
        }
    }

    @Override
    @Deprecated(since="9")
    protected void finalize() {}

    public void setThreadFactory(ThreadFactory threadFactory) {
        if (threadFactory == null)
            throw new NullPointerException();
        this.threadFactory = threadFactory;
    }

    public ThreadFactory getThreadFactory() {
        return threadFactory;
    }

    public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
        if (handler == null)
            throw new NullPointerException();
        this.handler = handler;
    }

    public RejectedExecutionHandler getRejectedExecutionHandler() {
        return handler;
    }

    public void setCorePoolSize(int corePoolSize) {
        if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
            throw new IllegalArgumentException();
        int delta = corePoolSize - this.corePoolSize;
        this.corePoolSize = corePoolSize;
        if (workerCountOf(ctl.get()) > corePoolSize)
            interruptIdleWorkers();
        else if (delta > 0) {
            // We don't really know how many new threads are "needed".
            // As a heuristic, prestart enough new workers (up to new
            // core size) to handle the current number of tasks in
            // queue, but stop if queue becomes empty while doing so.
            int k = Math.min(delta, workQueue.size());
            while (k-- > 0 && addWorker(null, true)) {
                if (workQueue.isEmpty())
                    break;
            }
        }
    }

    public int getCorePoolSize() {
        return corePoolSize;
    }

    public boolean prestartCoreThread() {
        return workerCountOf(ctl.get()) < corePoolSize &&
                addWorker(null, true);
    }

    void ensurePrestart() {
        int wc = workerCountOf(ctl.get());
        if (wc < corePoolSize)
            addWorker(null, true);
        else if (wc == 0)
            addWorker(null, false);
    }

    public int prestartAllCoreThreads() {
        int n = 0;
        while (addWorker(null, true))
            ++n;
        return n;
    }

    public boolean allowsCoreThreadTimeOut() {
        return allowCoreThreadTimeOut;
    }

    public void allowCoreThreadTimeOut(boolean value) {
        if (value && keepAliveTime <= 0)
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        if (value != allowCoreThreadTimeOut) {
            allowCoreThreadTimeOut = value;
            if (value)
                interruptIdleWorkers();
        }
    }

    public void setMaximumPoolSize(int maximumPoolSize) {
        if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
            throw new IllegalArgumentException();
        this.maximumPoolSize = maximumPoolSize;
        if (workerCountOf(ctl.get()) > maximumPoolSize)
            interruptIdleWorkers();
    }

    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }

    public void setKeepAliveTime(long time, TimeUnit unit) {
        if (time < 0)
            throw new IllegalArgumentException();
        if (time == 0 && allowsCoreThreadTimeOut())
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        long keepAliveTime = unit.toNanos(time);
        long delta = keepAliveTime - this.keepAliveTime;
        this.keepAliveTime = keepAliveTime;
        if (delta < 0)
            interruptIdleWorkers();
    }

    public long getKeepAliveTime(TimeUnit unit) {
        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
    }



    public BlockingQueue<Runnable> getQueue() {
        return workQueue;
    }


    public boolean remove(Runnable task) {
        boolean removed = workQueue.remove(task);
        tryTerminate(); // In case SHUTDOWN and now empty
        return removed;
    }


    public void purge() {
        final BlockingQueue<Runnable> q = workQueue;
        try {
            Iterator<Runnable> it = q.iterator();
            while (it.hasNext()) {
                Runnable r = it.next();
                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
                    it.remove();
            }
        } catch (ConcurrentModificationException fallThrough) {
            // Take slow path if we encounter interference during traversal.
            // Make copy for traversal and call remove for cancelled entries.
            // The slow path is more likely to be O(N*N).
            for (Object r : q.toArray())
                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
                    q.remove(r);
        }

        tryTerminate(); // In case SHUTDOWN and now empty
    }


    public int getPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // Remove rare and surprising possibility of
            // isTerminated() && getPoolSize() > 0
            return runStateAtLeast(ctl.get(), TIDYING) ? 0
                    : workers.size();
        } finally {
            mainLock.unlock();
        }
    }

    public int getActiveCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            int n = 0;
            for (ThreadPoolExecutor.Worker w : workers)
                if (w.isLocked())
                    ++n;
            return n;
        } finally {
            mainLock.unlock();
        }
    }

    public int getLargestPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            return largestPoolSize;
        } finally {
            mainLock.unlock();
        }
    }

    public long getTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (ThreadPoolExecutor.Worker w : workers) {
                n += w.completedTasks;
                if (w.isLocked())
                    ++n;
            }
            return n + workQueue.size();
        } finally {
            mainLock.unlock();
        }
    }

    public long getCompletedTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (ThreadPoolExecutor.Worker w : workers)
                n += w.completedTasks;
            return n;
        } finally {
            mainLock.unlock();
        }
    }

    @Override
    public String toString() {
        long ncompleted;
        int nworkers, nactive;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            ncompleted = completedTaskCount;
            nactive = 0;
            nworkers = workers.size();
            for (ThreadPoolExecutor.Worker w : workers) {
                ncompleted += w.completedTasks;
                if (w.isLocked())
                    ++nactive;
            }
        } finally {
            mainLock.unlock();
        }
        int c = ctl.get();
        String runState =
                isRunning(c) ? "Running" :
                        runStateAtLeast(c, TERMINATED) ? "Terminated" :
                                "Shutting down";
        return super.toString() +
                "[" + runState +
                ", pool size = " + nworkers +
                ", active threads = " + nactive +
                ", queued tasks = " + workQueue.size() +
                ", completed tasks = " + ncompleted +
                "]";
    }

    protected void beforeExecute(Thread t, Runnable r) { }

    /**
     * <pre> {@code
     * class ExtendedExecutor extends ThreadPoolExecutor {
     *   // ...
     *   protected void afterExecute(Runnable r, Throwable t) {
     *     super.afterExecute(r, t);
     *     if (t == null
     *         && r instanceof Future<?>
     *         && ((Future<?>)r).isDone()) {
     *       try {
     *         Object result = ((Future<?>) r).get();
     *       } catch (CancellationException ce) {
     *         t = ce;
     *       } catch (ExecutionException ee) {
     *         t = ee.getCause();
     *       } catch (InterruptedException ie) {
     *         // ignore/reset
     *         Thread.currentThread().interrupt();
     *       }
     *     }
     *     if (t != null)
     *       System.out.println(t);
     *   }
     * }}</pre>
     *
     * @param r the runnable that has completed
     * @param t the exception that caused termination, or null if
     * execution completed normally
     */
    protected void afterExecute(Runnable r, Throwable t) { }

    protected void terminated() { }

    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        public CallerRunsPolicy() { }

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

    public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() { }

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                    " rejected from " +
                    e.toString());
        }
    }

    public static class DiscardPolicy implements RejectedExecutionHandler {
        public DiscardPolicy() { }

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        public DiscardOldestPolicy() { }

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值