Threadpool源码分析-java并发编程(三)

2018-09-27  本文已影响23人  卫渐行

前面两章,我们介绍了CAS以及ReentrantLock的基本知识;现在我们先了解下threadPool的几种状态,以及几种默认实现(newFixedThreadPool,newCacheThreadPool,newSingleThreadPool,newScheduleThreadPool);

threadPool常见的几种状态

     *   RUNNING:  Accept new tasks and process queued tasks(接受新的任务,并且能够处理队列的中任务)
     *   SHUTDOWN: Don't accept new tasks, but process queued tasks(不能接受接受新任务,等待队列的任务处理完毕)
     *   STOP:     Don't accept new tasks, don't process queued tasks,
     *             and interrupt in-progress tasks(不再接受新的任务,不再处理队列的任务,并且中断正在执行的任务)
     *   TIDYING:  All tasks have terminated, workerCount is zero,(所有的任务已经中止,队列中任务数为零)
     *             the thread transitioning to state TIDYING
     *             will run the terminated() hook method
     *   TERMINATED: terminated() has completed(所有的任务处理完毕)

threadPool中几种任务之间的转换 ;特别注意状态转换的先后顺序;

  • RUNNING -> SHUTDOWN
    On invocation of shutdown(), perhaps implicitly in finalize()
    当调用shutdown方法以及显式的执行 finalize()方法;
  • (RUNNING or SHUTDOWN) -> STOP
    On invocation of shutdownNow()
    当调用shutdownNow()方法
  • SHUTDOWN -> TIDYING
    When both queue and pool are empty
    队列和pool中为空时
  • STOP -> TIDYING
    When pool is empty
    pool 为空
  • TIDYING -> TERMINATED
    When the terminated() hook method has completed
    terminated方法调用完成之后

ThreadPool中的常量解释

首先ThreadPoolExecutor,int整型中32位的前3位用来表示线程池状态,后3位表示线程池中有效的线程数。

  • COUNT_BITS =29,前三位为线程池状态,后面位数为线程池的个数
    private static final int COUNT_BITS = Integer.SIZE - 3;
  • CAPACITY = pow(2,29)-1
    private static final int CAPACITY = (1 << COUNT_BITS) - 1;
  • 特别注意到状态位左移之后的数值状态,同时注意几个状态之间大小比较 running<shutdown<stop<tidying<terminated
// runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;//前三位为111,后面全是零
    private static final int SHUTDOWN   =  0 << COUNT_BITS;//前三位000.后面全是零
    private static final int STOP       =  1 << COUNT_BITS;//前三位001,后面全是零
    private static final int TIDYING    =  2 << COUNT_BITS;//前面为010.后面全是零
    private static final int TERMINATED =  3 << COUNT_BITS;//前面为011,后面全是零
  • 根据上面的几个常量,我们清楚线程状态由int高三位决定,数目由低29位决定;通过下面的两个方法workerCountOf(), workerCountOf();能够获取到int对应高三位,以及低29位的值;即int对应的状态位,以及线程池的容量大小;
// 得到线程数;CAPACITY bit数据位具体为 00011111111111111111111111111111。 
//与操作的话前面3位肯定为0,相当于直接取c的后29位的值
private static int workerCountOf(int c)  {
 return c & CAPACITY; 
}
// 得到状态; CAPACITY的非操作得到的二进制位11100000000000000000000000000000,然后做在一个与操作,相当于直接取前3位的的值
private static int runStateOf(int c)     { 
    return c & ~CAPACITY; 
}

-初始化int,即线程池在运行,但是count为0的时候;
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

上一篇下一篇

猜你喜欢

热点阅读