zoukankan      html  css  js  c++  java
  • 并发编程学习笔记(三十三、线程池源码三,线程池状态)

    目录:

    • 位运算复习
    • 线程池状态解析

    位运算复习

    原码:一个整数的绝对值转换成二进制,若此数为整数最高位为0,为负数最高位为1。

    反码:除最高位的整数标记外,其它数均由0变1,1变0。

    补码:反码+1。

    注:计算机中不管正数还是负数都用二进制的补码表示,正数的原码、反码、补码都一样

    ——————————————————————————————————————————————————————————————————————

    示例1:-1

    • 原码:1000 0000 0000 0000 0000 0000 0000 0001
    • 反码:1111 1111 1111 1111 1111 1111 1111 1110
    • 补码:1111 1111 1111 1111 1111 1111 1111 1111

    示例2:-2

    • 原码:1000 0000 0000 0000 0000 0000 0000 0010
    • 反码:1111 1111 1111 1111 1111 1111 1111 1101
    • 补码:1111 1111 1111 1111 1111 1111 1111 1110

    示例3:2

    • 原码:0000 0000 0000 0000 0000 0000 0000 0010
    • 反码:0000 0000 0000 0000 0000 0000 0000 0010
    • 补码:0000 0000 0000 0000 0000 0000 0000 0010

    线程池状态解析

    1、基本属性:

    1 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    2 private static final int COUNT_BITS = Integer.SIZE - 3;
    3 private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    • ctl包含两部分信息:runState=线程池状态,workerCount=有效的工作线程数。
    • COUNT_BITS:29
    • CAPACITY:工作线程最大容量,即0001 1111 1111 1111 1111 1111 1111 1111。

    为啥ctlctl会包含两部分信息呢,因为总共有5个状态,所以用3个bit就能表示了,也就是高3为来表示;故低29位就可以表示工作线程数,即最多为2^29-1:536870911,5亿多

    2、线程池状态:

    • RUNNING:接收新的任务,并且执行阻塞队列的任务。
    • SHUTDOWN:不接收新的任务,但可以执行阻塞队列的任务。
    • STOP:不接收新的任务,也不可以执行阻塞队列的任务。
    • TIDYING:所有任务都已终止(工作线程数为0),进入TIDYING状态会执行terminated()方法。
    • TERMINATED:terminated()方法执行完后进入TERMINATED状态。
    1 private static final int RUNNING    = -1 << COUNT_BITS;
    2 private static final int SHUTDOWN   =  0 << COUNT_BITS;
    3 private static final int STOP       =  1 << COUNT_BITS;
    4 private static final int TIDYING    =  2 << COUNT_BITS;
    5 private static final int TERMINATED =  3 << COUNT_BITS;

    3、操作方法:

    1 /** 得到运行状态,即保留高3位 **/
    2 private static int runStateOf(int c)     { return c & ~CAPACITY; }
    3 /** 得到工作线程数量,及保留低29位 **/
    4 private static int workerCountOf(int c)  { return c & CAPACITY; }
    5 /** 初始化ctl **/
    6 private static int ctlOf(int rs, int wc) { return rs | wc; }
     1 /**
     2  * 判断线程池状态是否小于s
     3  */
     4 private static boolean runStateLessThan(int c, int s) {
     5     return c < s;
     6 }
     7 
     8 /**
     9  * 判断线程池状态是否大于等于s
    10  */
    11 private static boolean runStateAtLeast(int c, int s) {
    12     return c >= s;
    13 }
    14 
    15 /**
    16  * 判断线程池状态是否处于运行中
    17  */
    18 private static boolean isRunning(int c) {
    19     return c < SHUTDOWN;
    20 }
     1 /**
     2  * CAS增加1个工作线程数
     3  */
     4 private boolean compareAndIncrementWorkerCount(int expect) {
     5     return ctl.compareAndSet(expect, expect + 1);
     6 }
     7 
     8 /**
     9  * CAS减少1个工作线程数
    10  */
    11 private boolean compareAndDecrementWorkerCount(int expect) {
    12     return ctl.compareAndSet(expect, expect - 1);
    13 }
    14 
    15 /**
    16  * 尝试CAS方式将工作线程数减1
    17  * 仅在线程突然终止时才调用
    18  */
    19 private void decrementWorkerCount() {
    20     do {} while (! compareAndDecrementWorkerCount(ctl.get()));
    21 }

    ——————————————————————————————————————————————————————————————————————

  • 相关阅读:
    N in 1 & 多重引导光盘制作
    可启动 ISO 合并、Windows 安装光盘合集
    VS 2005 VC++ 文件类型
    Windows 无人值守安装应答文件详解
    30种下载Youtube视频的方法
    解释YOUTUBE FLV 地址
    Windows下进程通信方式[转]
    进程通讯 DELPHI的类实现
    c#.net常用函数列表
    Javascript, How to make a Dress Up Game (Drag and Drop)
  • 原文地址:https://www.cnblogs.com/bzfsdr/p/13355921.html
Copyright © 2011-2022 走看看