shutdown与shutdownNow的对比
/** * 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. * * <p>This method does not wait for previously submitted tasks to * complete execution. Use {@link #awaitTermination awaitTermination} * to do that. * * @throws SecurityException {@inheritDoc} */ public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); advanceRunState(SHUTDOWN); interruptIdleWorkers(); onShutdown(); // hook for ScheduledThreadPoolExecutor } finally { mainLock.unlock(); } tryTerminate(); }
其中,private final ReentrantLock mainLock = new ReentrantLock();
使用了锁。
checkShutdownAccess方法进行了安全检查。
/** * 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(); } } }
/** * The main pool control state, ctl, is an atomic integer packing * two conceptual 概念 fields * workerCount, indicating 指示 the effective 有效的 number of threads * runState, indicating whether running, shutting down etc 等 * * In order to pack them into one int, we limit workerCount to * (2^29)-1 (about 500 million) threads rather than 而不是(2^31)-1 (2 * billion) otherwise 否则,另 representable 代表. If this is ever an issue 问题 in * the future, the variable can be changed to be an AtomicLong, * and the shift/mask constants constants 常数 below adjusted. But until the need * arises 出现, this code is a bit faster and simpler using an int. * * The workerCount is the number of workers that have been * permitted 允许 to start and not permitted to stop. The value may be * transiently 瞬变 different from the actual number of live threads, * for example when a ThreadFactory fails to create a thread when * asked, and when exiting 退出 threads are still performing 执行 * bookkeeping 记账 before terminating 终止. The user-visible pool size is * reported as the current size of the workers set. * * The runState provides the main lifecycle control, taking on values: * * RUNNING: Accept new tasks and process queued tasks * SHUTDOWN: Don‘t accept new tasks, but process queued tasks * STOP: Don‘t accept new tasks, don‘t process queued tasks, * and interrupt in-progress 执行中 tasks * TIDYING: All tasks have terminated, workerCount is zero, * the thread transitioning 过渡 to state TIDYING * will run the terminated() hook method * TERMINATED: terminated() has completed * * The numerical order among these values matters, to allow * ordered comparisons 比较. The runState monotonically 单调的、无变化的 increases over 增加超过 * time, but need not hit each state. The transitions are: * * RUNNING -> SHUTDOWN * On invocation of shutdown(), perhaps implicitly in finalize() * (RUNNING or SHUTDOWN) -> STOP * On invocation of shutdownNow() * SHUTDOWN -> TIDYING * When both queue and pool are empty * STOP -> TIDYING * When pool is empty * TIDYING -> TERMINATED * When the terminated() hook method has completed * * Threads waiting in awaitTermination() will return when the * state reaches TERMINATED. * * Detecting the transition from SHUTDOWN to TIDYING is less * straightforward than you‘d like because the queue may become * empty after non-empty and vice versa during SHUTDOWN state, but * we can only terminate if, after seeing that it is empty, we see * that workerCount is 0 (which sometimes entails a recheck -- see * below). */
原文:https://www.cnblogs.com/coolgame/p/12031307.html