了解下JUC的线程池学习三

1.线程池的状态常量,这里只详细分析其中一个,其他类同,这里看RUNNING状态:

    // -1的补码为:111-11111111111111111111111111111
    // 左移29位后:111-00000000000000000000000000000
    // 10进制值为:-536870912
    // 高3位111的值就是表示线程池正在处于运行状态
    private static final int RUNNING = -1 << COUNT_BITS;
 

 

2.控制变量ctl的组成就是通过线程池运行状态rs和工作线程数wc通过或运算得到的:

   // rs=RUNNING值为:111-00000000000000000000000000000
   // wc的值为0:000-00000000000000000000000000000
   // rs | wc的结果为:111-00000000000000000000000000000
   private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
   private static int ctlOf(int rs, int wc) {
          return rs | wc;
   }

   那么我们怎么从ctl中取出高3位?上面源码中提供的runStateOf()方法就是提取运行状态:

   // 先把COUNT_MASK取反(~COUNT_MASK),得到:111-00000000000000000000000000000
   // ctl位图特点是:xxx-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
   // 两者做一次与运算即可得到高3位xxx
   private static int runStateOf(int c){
         return c & ~COUNT_MASK;
   }

   同理,取出低29位只需要把ctlCOUNT_MASK(000-11111111111111111111111111111)做一次与运算即可。

   

 

  注:这里有一个比较特殊的技巧,由于运行状态值存放在高3位,

         所以可以直接通过十进制值(甚至可以忽略低29位,直接用ctl进行比较,或者使用ctl和线程池状态常量进行比较

        来比较和判断线程池的状态:

                RUNNING(-536870912) < SHUTDOWN(0) < STOP(536870912) < TIDYING(1073741824) < TERMINATED(1610612736)

   下面这三个方法就是使用这种技巧:

    // ctl和状态常量比较,判断是否小于
    private static boolean runStateLessThan(int c, int s) {
                  return c < s;
    }

    // ctl和状态常量比较,判断是否小于或等于
    private static boolean runStateAtLeast(int c, int s) {
               return c >= s;
    }

    // ctl和状态常量SHUTDOWN比较,判断是否处于RUNNING状态
    private static boolean isRunning(int c) {
          return c < SHUTDOWN;
    }

   最后是线程池状态的跃迁图:

   

 

 

 PS:线程池源码中有很多中间变量用了简单的单字母表示,例如c就是表示ctl、wc就是表示worker count、rs就是表示running status。

 

学习来源:https://www.cnblogs.com/throwable/p/13574306.html

posted @ 2020-09-02 15:55  小窝蜗  阅读(288)  评论(0编辑  收藏  举报