java 线程池 状态_Java 线程池 的几个状态 详解

Java提供的几个线程池,最终都是使用 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;

// runState is stored in the high-order bits

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;

// Packing and unpacking ctl

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; }

/*

* Bit field accessors that don't require unpacking ctl.

* These depend on the bit layout and on workerCount being never negative.

*/

private static boolean runStateLessThan(int c, int s) {

return c < s;

}

private static boolean runStateAtLeast(int c, int s) {

return c >= s;

}

private static boolean isRunning(int c) {

return c < SHUTDOWN;

}

源码里面有这么点属性和简单方法,都是最基本的,绕不开的东西。了解一下。

4c1e46164edb01d90516ec53b5071d9b.png

1,首先是一个原子类 AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

这个是在多线程操作的时候,记录线程池的一些状态和池里面线程的数量的载体。使用原子类,是为了线程安全。

源码中说,现阶段,暂时使用一个int类型的数字来表示信息,基本差不多够用了,里面可以包含2的29次方-1的线程数,差不多500million(百万),源码注释这么写的。要是后期不够用了,还可以扩展为long类型

2,int  类型的 COUNT_BITS = Integer.SIZE - 3;

/**

* COUNT_BITS 详解

*/

@Test

public void showCountBits() {

// 29 Integer.SIZE=32 意思就是integer使用了多少位来表达一个int数字。

System.out.println(Integer.SIZE);

// 4个字节,一个字节(byte)8位(bit)

System.out.println(Integer.BYTES);

System.out.println(COUNT_BITS);

System.out.println();

}

运行结果:

a6653cb78113a6906f8e6b4a3afe23d4.png

这个就解释了,这个数字  29哪里来的。

这个属性,就是说 属性  ctl 的29位来表示 work counter

3,int 类型的 CAPACITY   = (1 << COUNT_BITS) - 1;

@Test

public void showCapacity() {

// 二进制:000 + 29个1,的int值。

showOne("CAPACITY", CAPACITY);

// 二进制:111 + 29个0,的int值

showOne("~CAPACITY", ~CAPACITY);

int i = 7 & CAPACITY;

System.out.println("111 & CAPACITY: " + (Integer.toBinaryString(i)));

System.out.println();

// 32位中,第一位是0,其它的都是1,即 Integer.MAX_VALUE = 0 + 31 个1

System.out.println("Integer.MAX_VALUE 二进制:" + Integer.toBinaryString(Integer.MAX_VALUE));

System.out.println("Integer.MAX_VALUE 二进制的长度:" + Integer.toBinaryString(Integer.MAX_VALUE).length());

i = Integer.MAX_VALUE & ~CAPACITY;

System.out.println("Integer.MAX_VALUE & ~CAPACITY: " + (Integer.toBinaryString(i)));

System.out.println("Integer.MAX_VALUE & ~CAPACITY: " + (Integer.toBinaryString(i)).length());

}

运行结果:

661d746f4e69496bb593d5be01ab06f4.png

容量:29个1,取反之后,就是111+29个0,然后 & 与运算,

runStateOf()方法是对 ~CAPACITY 与的,其实就是取int的前3位的值

workerCountOf()方法是对 CAPACITY 与的,其实就是取int的后29位的值

由此,int属性的32个二进制位都用来干吗的就分配完了。

4,线程池的几个状态

// runState is stored in the high-order bits

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;

/**

* 看看线程池的几个状态数字

* 这么看就明白了后面29个位,来控制线程的数量count,前面3位来表示线程池的状态,全1的即111表示running,

* 000-011是递增关系,同时也是线程池状态的衰败过程。

*/

@Test

public void showState() {

//111 - (29个0)

showOne("RUNNING", RUNNING);

//000 - (29个0)

showOne("SHUTDOWN", SHUTDOWN);

//001 - (29个0)

showOne("STOP", STOP);

//010 - (29个0)

showOne("TIDYING", TIDYING);

//011 - (29个0)

showOne("TERMINATED", TERMINATED);

}

运行结果:

9bd79f015d0789a43dd04cdd4b9c9882.png

这么看一下,线程池的几个状态,其实就是int的前3位来表示的;

全1的即111表示running,

debd0d67d0d992e1daf11b799479f117.png

(-1 << 29  :那就是32个1,左移29位,那就只剩下111 + 29个0啦,running的状态就是这么来的。)

000-011是递增关系,同时也是线程池状态的衰败过程。还预留了些位置,以备后用。

线程池几个状态之间的关系变化图

d66d73ca4c86a4ef2afd617b22487b0f.png

这个在源码的注释中也有写。

90854c1918186d151fa361931f719d6d.png

使用到的打印一个int数字的方法:

private void showOne(String name, int aInt) {

System.out.println(name + "的信息");

System.out.println("原始int值:" + aInt);

System.out.println("二进制的值:" + Integer.toBinaryString(aInt));

System.out.println("二进制的值的字符串的长度:" + Integer.toBinaryString(aInt).length());

System.out.println("--------------------------");

System.out.println();

}

5,线程池的2个关键数字

/**

* 线程池中的2个数字

* 1,线程池的状态

* 2,线程池中的线程数

*/

@Test

public void twoCountInPool() {

int c = ctl.get();

System.out.println("线程池的2个关键数字。。。");

poolState(c);

workerCount(c);

System.out.println();

}

/**

* 获取线程池的当前状态

*/

private void poolState(int c) {

System.out.println("线程池的状态。。。");

int i = runStateOf(c);

showOne("test state", i);

System.out.println();

}

/**

* 获取线程池中当前的线程数

*/

private void workerCount(int c) {

System.out.println("线程池的线程数。。。");

int i = workerCountOf(c);

System.out.println("worker count is " + i);

}

运行结果:

82e657e8c03ddad70a9410e386351dcf.png

默认是running状态,0个worker。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值