ThreadPoolExecutor源码涉及到的内容比较多,需要一点点的去啃和查看…
ThreadPoolExecutor的核心属性
ThreadPoolExecutor的核心属性主要就是CTL。基于CTL获取到线程池的状态以及工作线程个数。
- ctl是一个int类型的整数,內部基于AtomicInteger(原子整数)包装了一层,有点类似于装饰者模式,保证在进行运算时是原子性的。
- ctl代表者线程中的两个核心的状态。分别是线程池的状态、工作线程的数量。
- 线程池的状态:使用ctl的高3位表示
- 工作线程的数量:使用ctl的低29位表示。
- private static final int COUNT_BITS = Integer.SIZE - 3:中COUNT_BITS是在获取位数。Integer.SIZE是整数类型的比特位数32位-3那就是29;
- private static final int CAPACITY = (1 << COUNT_BITS) - 1:将1左移29位置-1那就是得到了最大的线程个数。
- 00100000 00000000 00000000 00000000
- 00000000 00000000 00000000 00000001
- 00011111 11111111 11111111 11111111
// 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;
上述的5个private定义的是代表线程池的五大状态。其中只有RUNNING状态代表线程池可以正常接收任务。
- RUNNING状态:-1左移29位得到的高三位是111。代表可以处理任务并且可以处理阻塞队列中的任务。
- SHUTDOWN状态:高三位000,不会接收任务。但是正在处理的任务会正常进行,阻塞队列中的任务也会正常进行。
- STOP状态:高三位001,不会接收新任务,正在处理任务的线程会被中断,阻塞队列中的任务不去处理。
- TIDYING状态:高三位010,这个状态代表着从SHUTDOWN或者STOP状态转换过来。代表着线程池马上关闭但是还没有关闭。是一个过渡状态。
- TERMINATED状态:高三位011,该状态是TIDYING状态转换而来,该状态只需要执行一个TERMINATED方法,这个方法需要自己去实现相关的业务逻辑。
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
- 上述两个方法显而易见需要ctl传递参数进来,涉及到并发需要实时获取准确值
- runStateOf 是基于与运算。 ~CAPACITY是取反操作然后和c与运算。显而易见是只会会得到高3位的值
- workerCountOf同理只会得到低29位的值,也就是获取到当前的工作线程个数。