博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程池的状态分析
阅读量:4164 次
发布时间:2019-05-26

本文共 2454 字,大约阅读时间需要 8 分钟。

本文基于JDK1.8分析下线程池的状态,源码如下

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;// runState is stored in the high-order bitsprivate 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 ctlprivate 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=32;

COUNT_BITS = Integer.SIZE - 3=29;
这里涉及到一个向左位移操作,如
RUNNING = -1 << COUNT_BITS
很多同学可能对负数位移不太清楚,这里补充下小知识

-1二进制计算如下:

1、先取-1的原码:10000000 00000000 00000000 00000001 (取1的原码00000000 00000000 00000000 00000001再在最高位设置1)
2、得反码: 11111111 11111111 11111111 11111110(除符号位按位取反)
3、得补码: 11111111 11111111 11111111 11111111 (反码值+1)

位移操作

-1位移29位得:11100000 00000000 00000000 00000000

//将ctl封装和解析的三个方法//将ctl的值,取高3位的数值,即取状态private static int runStateOf(int c)     { return c & ~CAPACITY; }//将ctl的值 ,取低29位的值,即线程池容量private static int workerCountOf(int c)  { return c & CAPACITY; }//传入rs(状态)wc(线程池容量),取得ctlprivate static int ctlOf(int rs, int wc) { return rs | wc; }

线程池各个状态切换框架图

线程池各个状态切换框架图

其中AtomicInteger变量ctl的功能非常强大:利用低29位表示线程池中线程数,通过高3位表示线程池的运行状态:

1、RUNNING:-1 << COUNT_BITS,即高3位为111
2、SHUTDOWN: 0 << COUNT_BITS,即高3位为000
3、STOP : 1 << COUNT_BITS,即高3位为001
4、TIDYING : 2 << COUNT_BITS,即高3位为010
5、TERMINATED: 3 << COUNT_BITS,即高位为011

1、RUNNING

(1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。
(02) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

2、 SHUTDOWN

(1) 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。

(2) 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。

3、STOP

(1) 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。

(2) 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

4、TIDYING

(1) 状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。

(2) 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

5、 TERMINATED

(1) 状态说明:线程池彻底终止,就变成TERMINATED状态。

(2) 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

你可能感兴趣的文章
可遇见框架技术之面试问题
查看>>
系统设计类面试题
查看>>
架构师的职责都有哪些?
查看>>
看女程序员是怎么坑大师兄的, 网友: 真的惨,笑死我了!
查看>>
C/C++程序员面试基础知识(一)
查看>>
程序员提离职遭领导威胁,一线企业总监我都认识,我让你混不下去
查看>>
朝九晚六吊打互联网企业,程序员:又开始无脑吹国企了!
查看>>
网友话数万元转行程序员,但是却没人要,网友:是学历问题吗?
查看>>
程序员辞掉30W年薪接私活:6个月就能赚回30W,庆幸自己当初辞职
查看>>
马云四天三谈996被骂上热搜:抱歉,这届年轻人不好“骗”了!
查看>>
中国牛逼的程序员有哪些?入职华为两天转正,半个月升主任
查看>>
为什么大学里的计算机老师,不去大公司当程序员呢?
查看>>
eclipse的java facets的runtimes如何删除tomcat?
查看>>
oracle序列的cache_size说明
查看>>
oracle中两个时间戳相减得到间隔毫秒数
查看>>
Oracle中将毫秒数转换为timestamp类型的两种方法
查看>>
mybatis配置and rownum< minus 查询第几行到第几行数据的sql原型和mybatis原型。
查看>>
oracle的concat函数使用问题。
查看>>
eclipse编辑状态下怎样让指定行左移或右移?
查看>>
plsql developer如何导入导出表结构和数据以及如何复制表结构和数据?
查看>>