美文网首页
【并发】线程池Executor

【并发】线程池Executor

作者: 河神 | 来源:发表于2019-01-29 11:02 被阅读0次

    线程池的构成

    构造函数

        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) 
    
    • corePoolSize 核心线程维持的线程数量
    • maximumPoolSize 最大线程数
    • keepAliveTime 在当前线程大于核心线程数的时候,等待维持的时间,超过世界就会销毁线程
    • workQueue 保存任务的队列
    • threadFactory 创建新线程的工厂,需要继承ThreadFactory接口,实现newThread方法,实现此方法,可以自定义线程的名字,如果不定义,线程的名字位Thread-0之类的
    • handler 当达到线程池和等待队列都已经达到最大的时候,阻止新任务进入所执行的策略

    内容

    ctl变量

    • 使用AtomicInteger ctl变量来保存线程池的状态与线程池中线程的数量
        private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
        private static final int COUNT_BITS = Integer.SIZE - 3;//等于29
        //CAPACITY=
        private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    
        // runState is stored in the high-order bits
        //下面所有的都会向左位移29位,所以高3位表示状态
        private static final int RUNNING    = -1 << COUNT_BITS;
        private static final int SHUTDOWN   =  0 << COUNT_BITS;
        private static final int STOP       =  1 << COUNT_BITS;
        private static final int TIDYING    =  2 << COUNT_BITS;
        private static final int TERMINATED =  3 << COUNT_BITS;
    

    其中高3位用来保存线程池的状态,低29位用来保存线程的数量
    其中0代表SHUTDOWN,-1代表RUNNING

    ctl 变量的位分布.png
    例如获取当前线程的方法
    private static int workerCountOf(int c) { 
        return c & CAPACITY; 
    }
    

    即为:
    11100000000000000000000000000001&00011111111111111111111111111111
    得到的自然是ctl中的线程池数量的值

    RejectedExecutionHandler 拒绝策略

    AbortPolicy:直接抛出异常【线程池默认使用】
    CallerRunsPolicy :只要线程池未关闭,该策略直接在调用者线程中运行当前被丢弃的任务。显然这样不会真的丢弃任务,但是,调用者线程性能可能急剧下降。
    DiscardOldestPolicy :当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。也就是丢弃最老的一个请求任务,也就是丢弃一个即将被执行的任务,并尝试再次提交当前任务。
    DiscardPolicy:直接丢弃要执行的任务

    execute()与submit()的执行

    线池程顺序

    线程池执行.png

    相关文章

      网友评论

          本文标题:【并发】线程池Executor

          本文链接:https://www.haomeiwen.com/subject/yclsdqtx.html