每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

线程池的状态及其处理的技巧

线程池的状态及其处理的技巧

线程的状态

线程池有5种状态:

  • Running,:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理

  • SHUTDOWN,:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务

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

  • TIDYING:当所有的任务已终止,ctl记录的"任务数量"为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。

    • 例如:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING
  • TERMINATED:线程池彻底终止,就变成TERMINATED状态

线程池的状态量
1 private static final int RUNNING    = -1 << COUNT_BITS;	-- 对应的高3位值是111。
2 private static final int SHUTDOWN   =  0 << COUNT_BITS;	-- 对应的高3位值是000。
3 private static final int STOP       =  1 << COUNT_BITS;	-- 对应的高3位值是001。
4 private static final int TIDYING    =  2 << COUNT_BITS;	-- 对应的高3位值是010。
5 private static final int TERMINATED =  3 << COUNT_BITS;	-- 对应的高3位值是011。

线程池使用一个原子整型来控制线程池的状态:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
  • ctl是原子整形,cas锁,操作具有原子、有序、可见性

  • ctl分为两个组成部分,一个是runState(线程池状态),一个是workerCount(工作线程数)

  • ctlof将两个状态进行打包:

    private static int ctlOf(int rs, int wc) { return rs | wc; }
    

    因为连个状态占据的是高3位和低29位所以不会冲突

状态获取
1 //拆包函数
2 private static int runStateOf(int c)     { return c & ~CAPACITY; }
3 private static int workerCountOf(int c)  { return c & CAPACITY; }
4 //打包函数
5 private static int ctlOf(int rs, int wc) { return rs | wc; }

主要通过COUNT_BITSCAPACITY获取状态

1 private static final int COUNT_BITS = Integer.SIZE - 3;
2 private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
posted @ 2021-06-16 19:11  雨下整夜~  阅读(223)  评论(0)    收藏  举报