【java多线程】线程池
线程池核心原理:https://www.zhihu.com/question/485071288?utm_id=0
一、线程池提交任务的执行示意图
二、线程池的核心参数解释
- corePoolSize:核心线程数大小:不管它们创建以后是不是空闲的。线程池需要保持 corePoolSize 数量的线程,除非设置了 allowCoreThreadTimeOut。
- maximumPoolSize:最大线程数:线程池中最多允许创建 maximumPoolSize 个线程。
- keepAliveTime:存活时间:如果经过 keepAliveTime 时间后,超过核心线程数的线程还没有接受到新的任务,那就回收。
- unit:keepAliveTime 的时间单位。
- workQueue:存放待执行任务的队列:当提交的任务数超过核心线程数大小后,再提交的任务就存放在这里。它仅仅用来存放被 execute 方法提交的 Runnable 任务。所以这里就不要翻译为工作队列了,好吗?不要自己给自己挖坑。
- threadFactory:线程工程:用来创建线程工厂。比如这里面可以自定义线程名称,当进行虚拟机栈分析时,看着名字就知道这个线程是哪里来的,不会懵逼。
- handler :拒绝策略:当队列里面放满了任务、最大线程数的线程都在工作时,这时继续提交的任务线程池就处理不了,应该执行怎么样的拒绝策略。
三、线程池管理线程池状态和线程数的机制
/** * ~:按位取反运算=>1则为0,0则为1 * &:按位与运算=>对位上的数字,1&1=1 1&0=0 0&0=0 * |:按位或运算=>对位上的数字,1|0=1 0|1=1 0|0=0 * <<:左移运算符,向左移动,高位移出,低位补0 * * * 1的二进制:0000_0000_0000_0000_0000_0000_0000_0001 * 1的反码为:1111_1111_1111_1111_1111_1111_1111_1110 * -1的二进制(1的补码):1111_1111_1111_1111_1111_1111_1111_1111 * * * int占8字节,既32位,最高位为0,表示正数,若为1表示负数 * 原码:1个数的二进制 * 反码:对原码的二进制位上的数取反 * 补码是:在反码的基础上+1,就是原码的补码。 * * 案例如下: * 1、先取1的原码:00000000 00000000 00000000 00000001 * 2、得反码: 11111111 11111111 11111111 11111110 * 3、得补码: 11111111 11111111 11111111 11111111 */ /** * 初始值==>二进制的:1110_0000_0000_0000_0000_0000_0000_0000 * * 该数字 * =>高3位为线程池的状态 * =>低29位为线程池的工作线程数 */ private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); /** * 32-3=29 */ private static final int COUNT_BITS = Integer.SIZE - 3; /** * 二进制:0001_1111_1111_1111_1111_1111_1111_1111 */ private static final int CAPACITY = (1 << COUNT_BITS) - 1; /** * -1<<29位 * -1的二进制:1111_1111_1111_1111_1111_1111_1111_1111 * 转换成二进制的数值 * 1110_0000_0000_0000_0000_0000_0000_0000 */ private static final int RUNNING = -1 << COUNT_BITS; /** * 0<<29位 * 0的二进制:0000_0000_0000_0000_0000_0000_0000_0000 * 转换成二进制的数值 * 0000_0000_0000_0000_0000_0000_0000_0000 */ private static final int SHUTDOWN = 0 << COUNT_BITS; /** * 1<<29位 * 1的二进制:0000_0000_0000_0000_0000_0000_0000_0001 * 转换成二进制 * 0010_0000_0000_0000_0000_0000_0000_0000 */ private static final int STOP = 1 << COUNT_BITS; /** * 2<<29位 * 2的二进制:0000_0000_0000_0000_0000_0000_0000_0010 * 转换成二进制 * 0100_0000_0000_0000_0000_0000_0000_0000 */ private static final int TIDYING = 2 << COUNT_BITS; /** * 3<<29位 * 3的二进制:0000_0000_0000_0000_0000_0000_0000_0011 * 转换成二进制 * 0110_0000_0000_0000_0000_0000_0000_0000 */ private static final int TERMINATED = 3 << COUNT_BITS; /** * 计算线程状态 * @param c * @return */ private static int runStateOf(int c) { return c & ~CAPACITY; } /** * 计算工作线程数 * @param c * @return */ private static int workerCountOf(int c) { return c & CAPACITY; } /** * * @param rs * @param wc * @return */ private static int ctlOf(int rs, int wc) { return rs | wc; }