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