ThreadPoolExecutor系列说之由浅入深源码解说

本文将ThreadPoolExecutor高深的位运算转换为二进制,以便更直观的理解方法和属性的使用。对加入线程池,执行worker的线程,释放worker的线程,终止线程池等进行细致的理解,以求每个判断,每行代码都能理解。Doug Lea的ThreadPoolExecutor代码实现真的是我们学习的榜样

属性

NOTE: 代码中的位运算不好直观,我们学习时可以将他们转成十进制和二进制,直观便于理解。使用以下方法操作进制间的转换
1、二进制 -> 十进制 Integer.parseInt(“00111100”, 2)
2、十进制 -> 二进制 Integer.toBinaryString(1)

/**
 *
 * <pre>
 * ctl即是又是
 *   workerCount:表示有效的线程数
 *   runState:   表示线程池的状态
 * </pre>
 * <pre>
 *  Run state is stored in the high-order bits; worker count is stored in the low-order bits. 解释如下:
 *  | ---    高位   ---  |  ---   低位    ---    |
 *  |   -536870912  -->  0  -->  536870912      |
 *  | ---  线程状态  ---  |  ---  线程数量  ---   |
 *  所以线程状态的变化轨迹是从 -536870912 开始递增,一直到 0;线程数量的变化轨迹是从0 开始递增,一直到 536870912
 *  2. ctl直接等于 536870910,再定义两个线程,debug看效果 do it by practise
 *  </pre>
 *
 * <pre>
 * ctl的初始值:-536870912
 * ctl = ctlOf(RUNNING, 0): -536870912 -> 11100000000000000000000000000000 -> size: 32
 *  </pre>
 */
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));


// COUNT_BITS = 29
private static final int COUNT_BITS = Integer.SIZE - 3;


/**
 * <pre>
 * (1 << COUNT_BITS) = (1 << 29)        -> 536870912  ->   100000000000000000000000000000 -> size: 30
 * CAPACITY          = ((1 << 29) - 1)  -> 536870911  ->    11111111111111111111111111111 -> size: 29
 * ~CAPACITY         = ~((1 << 29) - 1) -> -536870912 -> 11100000000000000000000000000000 -> size: 32
 * </pre>
 */
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;


/**
 * NOTE: 这几个状态值是有数值顺序的,所以这几个状态值才可以进行大于、小于等操作
 *
 * runState is stored in the high-order bits
 * <pre>
 * COUNT_BITS = 29
 * RUNNING    (-1 << 29):   -536870912 -> 11100000000000000000000000000000 -> size: 32
 * SHUTDOWN   (0 << 29):    0          -> 0 ->                             -> size: 1
 * STOP       (1 << 29):    536870912  -> 100000000000000000000000000000   -> size: 30
 * TIDYING    (2 << 29):    1073741824 -> 1000000000000000000000000000000  -> size: 31
 * TERMINATED (3 << 29):    1610612736 -> 1100000000000000000000000000000  -> size: 31
 * </pre>
 * 
 * 通过实践得出:这里的常量只是状态的边界值。换句话说,每个状态其实是一个范围,具体如下
 * runState: -------   RUNNING  -------- )[ ----------    SHUTDOWN  --------- )[ ------------    STOP  ---------- )[ -------------    TIDYING  -------- )[  TERMINATED
 * 11100000000000000000000000000000    ~  0  ~  100000000000000000000000000000  ~  1000000000000000000000000000000  ~  1100000000000000000000000000000  ~ 无穷
 */
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;

下图为线程池的状态转换过程

状态方法

/**
 * 这个方法:返回负数说明线程状态是RUNNING;返回0说明线程状态是SHUTDOWN;理论上不返回正数
 *
 * <pre>
 * 由于
 * ~CAPACITY = ~((1 << 29) - 1) -> -536870912              -> 11100000000000000000000000000000 -> size: 32
 * ctl       = ctlOf(RUNNING,0) -> -536870912              -> 11100000000000000000000000000000 -> size: 32
 * 所以
 * c=ctl时,ctl & ~CAPACITY      -> -536870912 & -536870912 -> 11100000000000000000000000000000 = -536870912,
 * 所以
 * 随着ctl ++,runStateOf方法结果也是负数,并从-536870912开始递 +1,一直到 0,所以也可以是说负数表示线程状态是RUNNING(运行状态)时
 *
 * 举例:
 * 当第一次ctl ++后,ctl          -> -536870911              -> 11100000000000000000000000000001
 * 此时,ctl & ~CAPACITY         -> -536870911 & -536870912 -> 11100000000000000000000000000001 & 11100000000000000000000000000000
 * NOTE: 当runStateOf等于0时,线程状态就变成了SHUTDOWN
 * </pre>
 */
private static int runStateOf(int c)     { return c & ~CAPACITY; }


/**
 * <pre>
 * 由于
 * CAPACITY = (1 << 29) - 1    ->  536870911               ->    11111111111111111111111111111 -> size: 29
 * ctl   = ctlOf(RUNNING, 0)   -> -536870912               -> 11100000000000000000000000000000 -> size: 32
 * 所以
 * c=ctl时,ctl & CAPACITY      -> -536870912 & 536870911   -> 00000000000000000000000000000000  = 0
 * 所以
 * 随着ctl ++,所以workerCountOf方法结果从0开始递 +1,一直到 536870911
 * </pre>
 */
private static int workerCountOf(int c)  { return c & CAPACITY; }


private static int ctlOf(int rs, int wc) { return rs | wc; }

线程池的执行过程,

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值