线程池shutdown源码

  /**
 * Initiates an orderly shutdown in which previously submitted
 * tasks are executed, but no new tasks will be accepted.
 * Invocation has no additional effect if already shut down.
 * 执行一个顺序的shutdown操作,在此之前已提交的任务将会被执行,但不再接受新任务。
 * 如果线程池已经shutdown,调用此方法不会产生副作用。
 * <p>This method does not wait for previously submitted tasks to
 * complete execution.  Use {@link #awaitTermination awaitTermination}
 * to do that.
 * 此方法不会等待已提交的任务执行完成,需使用awaitTermination 来达到此目的
 * @throws SecurityException {@inheritDoc}
 */
public void shutdown() {
    //首先获得线程池的可重入锁
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
    	//检查shutdown的权限
        checkShutdownAccess();
        advanceRunState(SHUTDOWN);
        interruptIdleWorkers();
        //ScheduledThreadPoolExecutor的钩子函数
        onShutdown(); // hook for ScheduledThreadPoolExecutor
    } finally {
        mainLock.unlock();
    }
    tryTerminate();
}
  /**
     * If there is a security manager, makes sure caller has
     * permission to shut down threads in general (see shutdownPerm).
     * 如果存在安全管理器,请确保调用者有在一般情况下关闭线程的权限。
     * If this passes, additionally makes sure the caller is allowed
     * to interrupt each worker thread. This might not be true even if
     * first check passed, if the SecurityManager treats some threads
     * specially.
     * 如果这一条通过,还要确保调用者被允许中断每个工作线程。
     * 即使第一条过了,如果安全管理器对某些线程特殊处理,仍可能导致检查不通过。
     */
    private void checkShutdownAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(shutdownPerm);
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                for (Worker w : workers)
                    security.checkAccess(w.thread);
            } finally {
                mainLock.unlock();
            }
        }
    }

    /**
     * Transitions runState to given target, or leaves it alone if
     * already at least the given target.
     *	将线程池的运行状态置为指定的状态(即SHUTDOWN   =  0 << COUNT_BITS),如果已经>=SHUTDOWN,就无需处理了
     * @param targetState the desired state, either SHUTDOWN or STOP
     *        (but not TIDYING or TERMINATED -- use tryTerminate for that)
     */
    private void advanceRunState(int targetState) {
        for (;;) {
        //无限循环,只有满足已至少是SHUTDOWN,或者cas把状态变为SHUTDOWN成功才退出
            int c = ctl.get();
            //这里还一起把当前工作者数量也cas设置了,因为ctl的低29位是存储worker的计数的
            if (runStateAtLeast(c, targetState) ||
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }
    /**
     * Common form of interruptIdleWorkers, to avoid having to
     * remember what the boolean argument means.
     * interruptIdleWorkers的一般形式,避免需要记忆boolean 参数的意义
     */
    private void interruptIdleWorkers() {
        interruptIdleWorkers(false);
    }
private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                //当当前worker的线程t未被中断且空闲时才去尝试设置中断标志,其中w.tryLock()返回true表示拿到的worker w的独占锁,
                //说明此worker并非在执行,也就达到了不去中断正在执行线程的效果
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }
  private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
         {
		   public boolean tryLock()  { return tryAcquire(1); }
	
	        protected boolean tryAcquire(int unused) {
	        //AQS里面的cas操作
	            if (compareAndSetState(0, 1)) {
	                setExclusiveOwnerThread(Thread.currentThread());
	                return true;
	            }
	            return false;
	        }
       }

shutdown与shutdownNow很重要的区别就是shutdown只设置空闲线程的中断标志位,实现这个功能的前提是需要获得worker的独占锁,只有在worker不是在执行线程任务时,此独占锁才有可能被获得。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值