本文基于Java 1.8.0_121-b13版本
线程池主要是为了解决两个问题:
-
大量异步执行的任务执行时候性能的提升
-
对于线程资源和界限的控制
线程池里线程的创建规则如下:
-
调用ThreadPoolExecutor的execute提交线程,首先检查CorePool,如果CorePool内的线程小于CorePoolSize,新创建线程执行任务
-
如果当前CorePool内的线程大于等于CorePoolSize,那么将线程加入到workQueue,其类型为BlockingQueue
-
如果不能加入workQueue,在小于MaxPoolSize的情况下创建线程执行任务
-
如果线程数大于等于MaxPoolSize,那么执行拒绝策略
一些常量和成员变量
线程池的状态:
private static final int COUNT_BITS = Integer.SIZE - 3;
//Accept new tasks and process queued tasks
private static final int RUNNING = -1 << COUNT_BITS;
//Don't accept new tasks, but process queued tasks
private static final int SHUTDOWN = 0 << COUNT_BITS;
//Don't accept new tasks, don't process queued tasks,and interrupt in-progress tasks
private static final int STOP = 1 << COUNT_BITS;
//All tasks have terminated, workerCount is zero,the thread transitioning to state TIDYING will run the terminated() hook method
private static final int TIDYING = 2 << COUNT_BITS;
terminated() has completed
private static final int TERMINATED = 3 << COUNT_BITS;
这里需要复习下源码、补码、反码:
-
正数的原码、反码、补码都是一样的
-
在计算机底层,所有的数都是用补码来表示的
-
对于负数,反码为原码的除符号位以外全部取反,而补码为反码+1
-1的源码为10000000 00000000 00000000 00000001 -1的反码为11111111 11111111 11111111 11111110 -1的补码为11111111 11111111 11111111 11111111
上面线程池的状态就是用整数的前三位表示。
而对于线程的容量,用后面的29位表示:
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
其他重要的变量:
private final BlockingQueue<Runnable> workQueue;