• 线程池源码ThreadPoolExecutor分析


    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}
         */
    针对之前已经提交的任务进行有序的关闭,不再接收新的任务。如果已经shutdown了,调用这个方法不会有什么影响。该方法不会等待之前已经提交的任务执行完毕,awaitTermination方法才有这个效果。
    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();
                }
            }
        }

    然后下面的方法就是设置线程池的状态
    /*
     * Methods for setting control state
     */
    
    /**
     * Transitions runState to given target, or leaves it alone if
     * already at least the given target.
     *
     * @param targetState the desired state, either SHUTDOWN or STOP
     *        (but not TIDYING or TERMINATED -- use tryTerminate for that)
     */
    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

    用死循环

    这个方法也没什么东西,就是个判断  继续看  

    private static boolean runStateAtLeast(int c, int s) { return c >= s; }
     private static int ctlOf(int rs, int wc) { return rs | wc; }
    private static int workerCountOf(int c)  { return c & CAPACITY; }
        /**
    
         * 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).
         */
  • 相关阅读:
    hiho_1081_最短路径1
    hiho_1079_离散化
    hiho_1078_线段树区间修改
    hiho_1069_最近公共祖先3
    【.netcore学习】.netcore添加到 supervisor 守护进程自启动报错
    【.NetCore学习】ubuntu16.04 搭建.net core mvc api 运行环境
    【.NetCore学习】ASP.NET Core EF Core2.0 DB First现有数据库自动生成实体Context
    【vue基础学习】vue.js开发环境搭建
    【vue学习】vue中怎么引用laydate.js日期插件
    【年终总结】个人的2017年年终总结
  • 原文地址:https://www.cnblogs.com/coolgame/p/12031307.html
Copyright © 2020-2023  润新知