Skip to content

线程池种类

一、概述

java.util.concurrent.Executors 工具类提供四种常用线程池,底层均基于 ThreadPoolExecutor 实现,各自参数、队列、适用场景不同。

二、四种内置线程池详解

1. newFixedThreadPool 固定线程池

底层构造:

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

参数特征:

  • corePoolSize = maximumPoolSize = nThreads,无临时急救线程;
  • 阻塞队列:无界 LinkedBlockingQueue,容量 Integer.MAX_VALUE。 适用场景:任务量可控、执行耗时较长,需要限制并发峰值。 ⚠️ 风险:任务大量堆积会无限占用内存,引发OOM。

2. newSingleThreadExecutor 单线程池

底层构造:

java
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>()));
}

参数特征:

  • 核心线程、最大线程均为1,全程单线程串行执行;
  • 阻塞队列:无界 LinkedBlockingQueue。 适用场景:任务必须严格按FIFO顺序执行,不允许并发。 ⚠️ 风险:无界队列堆积任务,大量任务会OOM。

3. newCachedThreadPool 可缓存线程池

底层构造:

java
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<Runnable>());
}

参数特征:

  • corePoolSize=0,无常驻核心线程;
  • maximumPoolSize=Integer.MAX_VALUE,线程几乎无上限;
  • 空闲线程存活60秒,超时自动回收;
  • 队列:SynchronousQueue,不存储任务,任务直接转交线程。 适用场景:任务密集、单任务执行时间短,大量短时异步任务。 ⚠️ 风险:瞬间海量任务会创建大量线程,耗尽CPU/内存资源。

4. newScheduledThreadPool 定时延迟线程池

底层实现 ScheduledThreadPoolExecutor,继承 ThreadPoolExecutor

java
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
            new DelayedWorkQueue());
}

参数特征:

  • 自定义核心线程数,最大线程无上限;
  • 阻塞队列:DelayedWorkQueue 延时优先级队列,按任务执行时间排序;
  • 支持延迟执行、周期性定时任务。 适用场景:定时任务、延时任务、轮询调度业务。

三、总结对比

  1. newFixedThreadPool:固定并发数,长耗时任务,限制峰值;
  2. newSingleThreadExecutor:单线程串行,保证任务有序执行;
  3. newCachedThreadPool:短时密集任务,自动回收空闲线程;
  4. newScheduledThreadPool:支持延迟、周期定时调度。

四、生产规范提醒

参考阿里《Java开发手册-嵩山版》【强制】规范:禁止使用Executors创建线程池,必须手动实例化ThreadPoolExecutor,规避资源耗尽风险,具体弊端如下:

  1. newFixedThreadPool、newSingleThreadExecutor 底层队列是无界LinkedBlockingQueue,队列容量为Integer.MAX_VALUE,高并发下大量任务持续堆积,会占用大量堆内存,最终触发OOM内存溢出。
  2. newCachedThreadPool、newScheduledThreadPool 最大线程数设置为Integer.MAX_VALUE,突发海量任务时会无限新建线程,大量线程抢占CPU、内存,导致服务器资源耗尽、服务不可用。

正确生产写法

手动指定七大参数,使用有界阻塞队列,配置合理最大线程与拒绝策略:

java
ExecutorService pool = new ThreadPoolExecutor(
    8,
    16,
    60L,
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(100), // 有界队列
    Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.CallerRunsPolicy()
);

五、面试简答

问:Executors提供哪四种线程池,各自特点?为什么生产不建议使用? 答:

  1. Fixed固定线程池,线程数量固定,无界队列,限制并发;
  2. Single单线程池,仅一条工作线程,任务串行有序执行;
  3. Cached缓存线程池,核心线程0,无上限临时线程,60秒空闲回收,无队列缓冲;
  4. Scheduled定时线程池,专用延时优先级队列,支持延迟、周期任务。 禁止使用原因:Fixed、Single无界队列堆积任务会OOM;Cached、Scheduled最大线程无上限,突发流量创建海量线程耗尽服务器资源;线上需手动构造ThreadPoolExecutor,配置有界队列、可控最大线程。

Powered by VitePress 1.6.4 | 持续更新中