• ThreadPoolExecutor的runState和workCount变量怎么存储?


    在阅读Java线程池ThreadPoolExecutor源码的时候,发现它很巧妙地把线程池状态runState和线程数workCount两个变量存放在了一个int型变量里面

    我们先看一个数值,如下是一个32位int的二进制:

    0010 0000 0000 0000 0000 0000 0000 0001

    1)高位第一位表示符号,0是正数,1是负数

    2)高位第二位和第三位表示runState的绝对值(线程池运行状态),runState可取值(-1,0,1,2,3)分别表示(running,shutdown,stop,tidying,terminated)

    3)剩下的用来表示线程数workCount,这里表示仅有1个线程,总共可以存储2^29-1个线程,大概5亿个。

    如何存储在一个变量?

    这样的表示法,把状态和workCount存储在了一个int变量里,那么这个变量是怎么计算出来的呢?

    首先,我们先获得runState的值,比如:

    int runState = -1

    再把runState向左移位29位

    -1 << 29

    这样就得到了

    1010 0000 0000 0000 0000 0000 0000 0000

    假设现在有3个线程,那么workCount = 3,我们把上面得到得值再加上workCount,即按位或( | )运算,如下

    1010 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0011
    ---------------------------------------
    1010 0000 0000 0000 0000 0000 0000 0011

    上面,我们把runState和workCount存储在一个变量里,接下来我们看看如何把他们拆解开。

    如何取到runState?

    上面我们得到了一个变量

    1010 0000 0000 0000 0000 0000 0000 0011

    我们知道32位的二进制中,高位前三位其实就是runState,所以我们去除后面29位的值即可。我们只需要做一个按位与( & )运算

    1010 0000 0000 0000 0000 0000 0000 0011
    1110 0000 0000 0000 0000 0000 0000 0000
    ---------------------------------------
    1010 0000 0000 0000 0000 0000 0000 0000

    只需要把结果向右移位29位即可得到runState的值(ThreadPoolExecutor的runState是已经移位以后的值,与本文不同)

    如何取到workCount?

    后29位就是workCount的值,所以我们去除前3位的值即可。同样我们做一个按位与( & )运算

    1010 0000 0000 0000 0000 0000 0000 0011
    0001 1111 1111 1111 1111 1111 1111 1111
    ---------------------------------------
    0000 0000 0000 0000 0000 0000 0000 0011
  • 相关阅读:
    jdbc连接数据库 url
    解决IntelliJ IDEA 使用 TOMCAT 中文乱码问题
    web.xml 4.0 头部信息
    jar包冲突解决方案
    idea 快捷键
    基于单片机的车辆防碰撞及自动刹车系统(STC89C52RC芯片+超声波传感器HC-SR04+液晶屏1602+继电器+蜂鸣器)
    电子时钟万年历+51单片机+1602液晶屏+DS1302+DS18B20+按键
    1008 数组元素循环右移问题(PAT)
    1007 素数对猜想(PAT)
    1006 换个格式输出整数(PAT)
  • 原文地址:https://www.cnblogs.com/lay2017/p/10946928.html
Copyright © 2020-2023  润新知