美文网首页java 多线程编程JAVA语言Java
线程池之ThreadPoolExecutor状态控制

线程池之ThreadPoolExecutor状态控制

作者: 徐志毅 | 来源:发表于2018-04-07 23:58 被阅读0次

    读懂ThreadPoolExecutor执行原理,需要先掌握其状态控制的方式,因为使用了大量位运算,读起来有点吃力,所以单独用一篇文章分析。以下是ThreadPoolExecutor状态控制的主要变量和方法:

        //原子状态控制数
        private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
        //29比特位
        private static final int COUNT_BITS = Integer.SIZE - 3;
        //实际容量 2^29-1
        private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    
        // runState is stored in the high-order bits
        // runState存储在高位中
        private static final int RUNNING    = -1 << COUNT_BITS;
        private static final int SHUTDOWN   =  0 << COUNT_BITS;
        private static final int STOP       =  1 << COUNT_BITS;
        private static final int TIDYING    =  2 << COUNT_BITS;
        private static final int TERMINATED =  3 << COUNT_BITS;
    
        // Packing and unpacking ctl 打包和解压ctl
    
        // 解压runState
        private static int runStateOf(int c)     { return c & ~CAPACITY; }
        // 解压workerCount
        private static int workerCountOf(int c)  { return c & CAPACITY; }
        // 打包ctl
        private static int ctlOf(int rs, int wc) { return rs | wc; }
    

    线程池使用一个AtomicInteger的ctl变量将 workerCount(工作线程数量)和 runState(运行状态)两个字段压缩在一起 ,这种做法在在java源码里经常有出现,如在 ReentrantReadWriteLock 里就将一个int分成高16位和底16位,分别表示读锁状态和写锁状态。ThreadPoolExecutor里也是使用了同样的思想,表现得更加复杂。

    ThreadPoolExecutor用3个比特位表示runState, 29个比特位表示workerCount。因此这里需要特别说明的是:

    确切的说,当最大线程数量配置为Integer.MXA_VAULE时,ThreadPoolExecutor的线程最大数量依然是2^29-1

    目前来看这是完全够用的,但随着计算机的不断发展,真的到了不够用的时候可以改变为AtomicLong。这如同32位系统时间戳会在2038年01月19日03时14分07秒耗尽一样,当以后我们的系统线程能够超过2^29-1时,这些代码就需要调整了。对于未来,无限可能。

    思考一下为什么是29:3呢?
    这是因为我们的运营状态有5种,向上取2次方数,2^3 = 8。所以必须要3个比特位来表示各种状态。

    运行状态解释:

    状态 解释
    RUNNING 运行态,可处理新任务并执行队列中的任务
    SHUTDOW 关闭态,不接受新任务,但处理队列中的任务
    STOP 停止态,不接受新任务,不处理队列中任务,且打断运行中任务
    TIDYING 整理态,所有任务已经结束,workerCount = 0 ,将执行terminated()方法
    TERMINATED 结束态,terminated() 方法已完成
    整个ctl的状态,会在线程池的不同运行阶段进行CAS转换。

    多线程系列目录(不断更新中):
    线程启动原理
    线程中断机制
    多线程实现方式
    FutureTask实现原理
    线程池之ThreadPoolExecutor概述
    线程池之ThreadPoolExecutor使用
    线程池之ThreadPoolExecutor状态控制
    线程池之ThreadPoolExecutor执行原理
    线程池之ScheduledThreadPoolExecutor概述
    线程池的优雅关闭实践

    相关文章

      网友评论

        本文标题:线程池之ThreadPoolExecutor状态控制

        本文链接:https://www.haomeiwen.com/subject/ngyuhftx.html