线程池关闭源码

线程池的状态如下  

   private static final int RUNNING    = -1 << COUNT_BITS;//111 + 29个0
    private static final int SHUTDOWN   =  0 << COUNT_BITS;//全是0
    private static final int STOP       =  1 << COUNT_BITS;//001 + 29个0
    private static final int TIDYING    =  2 << COUNT_BITS;//010 + 29个0
    private static final int TERMINATED =  3 << COUNT_BITS;//011 + 29个0
COUNT_BITS 为29。-1在计算机中的补码是1111 1111,当左移29位后,就是最高的三位是111,剩下29位都是0。
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static int ctlOf(int rs, int wc) { return rs | wc; }

  所以这个ctl的初始值就是111 + 29个0

  二 shutdown

 public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();//忽略
            advanceRunState(SHUTDOWN);//高三位是000,除非ctl已经比000还大
            interruptIdleWorkers();
            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;//如果线程在工作,或者没有阻塞,那么该方法什么都没有干
                if (!t.isInterrupted() && w.tryLock()) {//如果tryLock能够返回true,说明啥说明该线程没有在干活,很可能是在从阻塞队列task,由于队列里没有任务导致阻塞
                    try {
                        t.interrupt();//执行中断,在worker的getTask方法是会抛出异常的,这会导致线程池中的线程退出
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

真正的执行关闭线程逻辑在 tryTerminate,前面只是在打扫战场,打扫的是已经空闲下来的线程,剩下的是

final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))//如果执行过shutdown 前两个判断就都是false,第三个条件如果任务队列不为空,就直接返回
                return;
            if (workerCountOf(c) != 0) { // Eligible to terminate 这个方法的意义,应该是把关闭行为传递下去,但是其实对于工作中的线程不会产生影响,但是如果任务队列为空同时执行过shutdown后,
                interruptIdleWorkers(ONLY_ONE);//中断可能在take方法阻塞的线程,这样线程就会执行完毕,线程数减一,此时线程池状态是SHUTDOWN,所以即使work数量小于coreSize也不会再次添加worker
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();//交给子类实现
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

   如果单看这个方法,第一次看人会很懵,因为前两个if,就会发现根本不会关闭线程池。想要理解这个问题,要结合runWorker方法和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.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;//直接返回null
            }

  这样worker线程的循环条件不满足,就会终止,执行finally里面的方法

final void runWorker(Worker w) {
        ...
        try {
            while (task != null || (task = getTask()) != null) {
                ...
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

  把线程remove掉,同时再次执行tryTerminate

private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

三 shutDownNow

  有了shutDown的分析,shutDownNow有几处差别,

  1 中断所有的worker,而shutDown是中断空闲worker

  2 把任务队列拷贝出来,并清空

  3 在上面的 getTask里判断大于等于STOP就不会判断任务队列直接返回null,这样worker线程就会直接退出循环

  

 
原文地址:https://www.cnblogs.com/juniorMa/p/13955811.html