Executors和ThreadPoolExecutor那种方式创建线程池更好

Executors和ThreadPoolExecutor那种方式创建线程池更好

  • 问题来源
  • 意外发现
  • 使用ThreadPoolExecutor 创建线程池池

问题来源

在一次使用阿里代码规约扫描历史项目时发现错误提示,提示内容如下图所示,我摘抄出部分关键信息供大家阅读。
线程池不应使用Executors去创建,而是通过ThreadPoolExecutor的方式。这样的处理方式让写的同学更加明确线程池的运行规则。规避资源耗尽的风险。
说明:Executors 返回的线程池弊端如下:

  • FixedThreadPool 和 SingleThreadPool:
    允许的请求队列长度为 Integer.MAX_VALUE。可能会对峙大量的请求。从而导致内存溢出。
  • CachedThreadPool:
    允许创建的线程数量为Integer.MAX_VALUE.可能会创建大量的线程。从而导致内存溢出。

Executors和ThreadPoolExecutor那种方式创建线程池更好_第1张图片

意外发现

Executors的底层竟然是使用ThreadPoolExecutor 来创建的。Executors只是在其基础之上加了不少限制封装。

   public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

使用ThreadPoolExecutor 创建线程池池

我们从jdk中可以看到ThreadPoolExecutor的构造器结构如下所示:

    public ThreadPoolExecutor(int corePoolSize, //线程池核心池大小
                              int maximumPoolSize,//线程池最大线程数量
                              long keepAliveTime,//当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
                              TimeUnit unit,//上一个参数的单位
                              BlockingQueue<Runnable> workQueue,//用来储存等待执行任务的队列。
                              ThreadFactory threadFactory //线程工厂
                              ) {
....
    }

通过构造器,我们很容易就可以创建一个属于自己的线程池

 ThreadPoolExecutor executor =
        new ThreadPoolExecutor(
            1,
            1,
            60,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1),
            new ThreadPoolExecutor.DiscardOldestPolicy());

如果觉得本文对你有所帮助,还请不吝打赏哦。

你可能感兴趣的:(java,架构设计)