【java多线程】线程池

一、线程池提交任务的执行示意图

二、线程池的核心参数解释

  • 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; }
View Code

四、java的队列解析

原文地址:https://www.cnblogs.com/shangxiaofei/p/13969904.html