线程池:ThreadPoolExcutor源码阅读

ThreadPoolExcutor源码流程图:(图片较大,下载再看比较方便)

线程池:ThreadPoolExcutor源码阅读

线程池里的二进制奥秘

前言:

线程池的五种状态state (RUNNING 、SHUTDOWN 、STOP 、TIDYING 、TERMINATED )和线程池的工作线程数:workerCount,

这两个变量,可有通过一个变量ctl 转成二进制后而获得。

直接看线程池ThreadPoolExecutor 源码里,管理状态和工作线程数的代码

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

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;

private static int runStateOf(int c)     { return c & ~CAPACITY; }
private static int workerCountOf(int c)  { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }

Integer.size 为Integer 类型最大值的二进制的位数:32 (位),COUNT_BITS = 29 (位),为啥是要要减去3 ,拿个29 呢,因为它想用二进制高3 位来表示线程池的状态(state ),后面的29 位用来表示工作线程数量(workerCount )。

比如RUNNINGZ 状态是-1 左移29 位,即:

-1 的二进制算法,先取绝对值1 的二进制:00000000 00000000 00000001 ,再取反码:11111111 11111111 11111110

再取补码(加1 ):11111111 11111111 11111111 ,这就是-1 的二进制表示。

左移运算:-1<

各个state :

-1<

0<< 29 =000 00000 00000000 00000000 => SHUTDOWN

1 <

2 <

3 <

线程池就是这样用高三位来表示不同的状态。

所以状态还有这样的关系: RUNNINGZ < SHUTDOWN < STOP < TIDYING < TERMINATED

不管各个状态低29 位是啥,这个关系都不会变。

再看CAPACITY = (1<

即00100000 00000000 00000000 – 1 = 00011111 11111111 11111111 ,这是线程池最大容量线程数(536870911 ),

即是用1 到29 位可表示线程的数量,那么,ctl = state.高3 位+低29 位,如:

ctl =111 11111 11111111 11111111 ,表示线程池是RUNNINGZ 状态,且线程数为536870911 ;

ctl =000 00000 00000000 00000001 ,表示线程池是SHUTDOWN 状态,且线程数为1 ;

CAPACITY=536870911 ,表示线程池最大线程数容量为536870911 ,但这个最大数值可以忽略,

因为在实例化线程池的时候,已经通过传参数设置了核心线程数、允许最大线程数。

初始化为 ctl = new AtomicInteger(ctlOf (RUNNING, 0));

ctlOf (RUNNING, 0)参数中的0 ,意思是初始化线程池的线程数为0 。然后通过ctlOf做或运算,即:

111 00000 00000000 00000000 | 00000000 00000000 00000000 =111 00000 00000000 00000000

运算后的结果,把表示状态的高3 位、表示线程数的低29 位组合起来得到一个数ctl ,

下次拿到ctl 之后,就知道此时线程池的状态和线程数量了。

1、那么runStateOf(int c)方法具体是怎么知道线程池的状态的?

假设c = ctl.get() =001 00000 00000000 00000011 ,表示STOP 状态且还有3 个线程

CAPACITY =(1<

为啥要减1 呢?因为减1 后:

1 、把表示状态的高3 位给挪留出来了,值又可以表示线程池最大线程数。

2 、把表示线程数的低29 位变为了1 ,那~CAPACITY = 11100000 00000000 00000000 , 所以:

c &~CAPACITY =001 00000 00000000 00000011 & 11100000 00000000 00000000 =001 00000 00000000 00000000 ,

结果001 00000 00000000 00000000 保持c 的高3 位不变,把c 的低29 位全变成0,这就是获得线程池是STOP 状态

2、通过workerCountOf(int c)获取工作线程数,同上理

Original: https://www.cnblogs.com/incognitor/p/16401160.html
Author: 無名之徒
Title: 线程池:ThreadPoolExcutor源码阅读

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622645/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • BASE64处理文件

    Base64: Base64是一种编码方式,基于64个ASCII字符来表示二进制数据,Base64将8个bit为一个单位的字节数据拆分为以6个bit为一个单位的二进制片段,每6个b…

    数据库 2023年6月9日
    092
  • 软件基础的理论(1)

    软件基础的理论 一, 什么是软件产品 它是一个逻辑产品,没有实体,包括程序,文档和数据,需要通过终端设备才能体现出来功能和作用 二, 软件产品的中间过程文档 客户需求 &#…

    数据库 2023年6月16日
    099
  • 容器化 | 在 S3 实现定时备份

    让我们来看看该功能是如何使用的。 [En] Let’s take a look at how this feature is used. 可用 Cron 表达式(与 L…

    数据库 2023年5月24日
    070
  • 《MySQL自传》

    撰写本文查阅了大量参考资料,也得到很多朋友的指点帮助,特别感谢: Jimmy Yang——阿里云数据库研究员,原Oracle InnoDB Architect. 彭立勋——华为云数…

    数据库 2023年6月11日
    088
  • 2022-8-17 mysql 第三天

    子查询 根据结果集中的行数,子查询可以分为以下几类: [En] According to the number of rows in the result set, subquer…

    数据库 2023年5月24日
    064
  • SQL的多表查询

    显示内连接: select 字段列表 from 表1 [inner] join 表2 on 连接条件; (PS:方括号(“[]”)内的为可选项;) (注意:…

    数据库 2023年5月24日
    0109
  • WIN10下启动VMware虚拟机蓝屏的解决办法

    问题: 每次启动虚拟机就会蓝屏,提示错误代码: PAGE_FAULT_IN_NONPAGED_AREA 解决办法: 禁用 Hyper-V 功能 打开”控制面板&#821…

    数据库 2023年6月14日
    087
  • 记一次部署系列:Mysql高可用之MHA

    参考:《Mysql高可用实践》——清华大学出版社2020年6月 环境:CentOS Linux release 7.7.1908 (Core) Mysql:…

    数据库 2023年5月24日
    090
  • MySQL 数据备份与恢复

    数据备份 使用 mysqldump 命令可以将数据库中的数据备份成一个文本文件,表的结构和数据以 SQL 的形式将存储生成的文本文件 mysqldump -u username -…

    数据库 2023年5月24日
    0125
  • Ansible—Inventory主机清单

    含义 清查;存货清单;财产目录;主机清单 1、增加主机组 &#x5B98;&#x65B9;&#x94FE;&#x63A5; http://docs….

    数据库 2023年6月14日
    096
  • Eureka详解系列(四)–Eureka Client部分的源码和配置

    按照原定的计划,我将分三个部分来分析 Eureka 的源码: 今天,我们来研究第二部分的源码。 我的思路是这样子的:先明确 Eureka Client 拥有哪些功能,然后从源码角度…

    数据库 2023年6月6日
    085
  • null和空字符串对于查询where条件语句的影响

    在数据库中我们进行数据处理的过程中,对于null值或者空字符串的情况对于这种数据我们进行计算平均值以及查询过程中如何进行对于这类数据的处理呢? step1:建表:create ta…

    数据库 2023年6月6日
    097
  • Centos7开放及查看端口

    Centos7开放及查看端口 1、开放端口 firewall-cmd –zone=public –add-port=5672/tcp –permanent # &#x…

    数据库 2023年6月6日
    0102
  • 994.腐烂的橘子

    994.腐烂的橘子 在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格;值 1 代表新鲜橘子;值 2 代表腐烂的橘子。每分钟,腐烂的橘…

    数据库 2023年6月16日
    087
  • mysql多实例部署

    在MySQL中配置多实例 1.软件下载 2.配置用户和组并解压二进制程序至/usr/local下 3.创建各实例数据存放的目录 4.初始化各示例 5.配置配置文件/etc/my.c…

    数据库 2023年5月24日
    089
  • 2_CSS

    1. 什么是CSS 1.1 什么是CSS Cascading Style Sheet 层叠样式表 是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一…

    数据库 2023年6月11日
    054
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球