Java 并发编程: ThreadPoolExecutor 详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shida_csdn/article/details/83278614

1.  使用线程池能解决两方面的问题

     a) 减少线程调用开销,提升性能;

     b) 通过限制线程数量达到限制程序资源占用的目的;

2.  线程创建的规则

     线程数小于 corePoolSize 时,新提交的任务会直接通过创建新线程执行,即使线程池中的线程是空闲的;

     线程数大于等于 corePoolSize 而又小于 maximumPoolSize 时,只有队列满了才会创建新线程执行任务;

     当任务不能被放入队列,创建新线程又会超过 maximumPoolSize 时,该任务会被 rejected;

     有一个超时时间设定,当线程数大于 corePoolSize 时,空闲时间超过超时阈值的线程会被销毁,

     当然这个超时时间也可以同时应用于 corePoolSize,需要设置参数 allowCoreThreadTimeOut 为 True;

3.  任务的安置优先级:先使用 corePool -> 再使用队列 -> 最后使用 maximumPool

     当 corePool 盛不下了,就先扔到队列里;

     队列也盛不下了,就继续建线程,直到达到上限;

4.  涉及的几种 BlockingQueue(无外乎,队列容量为 0、有限长、无限长三种喽!)

     SynchronousQueue : 不能存储任务(队列长度为 0),通常需要 maximumPoolSize 无界以避免抛 rejected;

     LinkedBlockingQueue : 无界队列,永远也存不满, maximumPoolSize 相当于失效;

     ArrayBlockingQueue : 有界队列,最正常的 BlockingQueue

5. 涉及的几种 reject 策略

    AbortPolicy : 抛出一个异常

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }

    CallerRunsPolicy : 调用者自己执行

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }

    DiscardPolicy:丢弃当前任务

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }

    DiscardOldestPolicy:丢弃最老的任务

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }

    RejectedExecutionHandler:用户可以自定义自己的 reject 策略

    

    

猜你喜欢

转载自blog.csdn.net/shida_csdn/article/details/83278614
今日推荐