线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式

/*1、corePoolSize线程池的常驻核心线程数
        2、maximumPoolSize能容纳的最大线程数,线程池中能够容纳同时执行的最大线程数,此值必须大于等于1
        3、keepAliveTime空闲线程存活时间,多余的空闲线程存活时间,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到剩下corePoolSize个线程为止
        4、unit 存活的时间单位,keepAliveTime单位
        5、workQueue 存放提交但未执行任务的队列,被提交但尚未被执行的任务
        6、threadFactory 创建线程的工厂类,用于创建线程,一般默认即可
        7、handler 等待队列满后的拒绝策略,表示当队列满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时如何来拒绝请求执行的runnable的策略*/
        ExecutorService newCacheThreadPool = new ThreadPoolExecutor(2, 5,
                1L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

  阿里巴巴Java开发手册明确表示不允许使用Executors去创建线程池,而是通过ThreadPoolExecutor方式创建,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

    说明: Executors返回的线程池对象的弊端如下:

  1) FixedThreadPool和SingleThreadPool:

    允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。(out of memory)

  2)CachedThreadPool和ScheduledThreadPool:

    允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM.

 

  拒绝策略JDK默认提供了4种:

  AbortPolicy(默认):直接抛出RejectedExecutionException异常组织系统正常运行

  CallerRunPolicy: "调用者运行"一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务五回退到调用者,从而降低新任务的流量。就是回退,谁启用的这个线程,就回退到哪,让调用者执行这个线程。

  DiscardOldestPolicy: 抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。

  DiscardPolicy: 该策略默默的丢弃无法处理的任务,不予任何处理也不抛出异常,如果允许任务丢失,这是最好的一种策略。

  

posted @ 2020-09-23 17:13  萧暮  阅读(656)  评论(0编辑  收藏  举报