跳转至

线程池的种类、区别与使用场景

一、FixedThreadPool

ExecutorService pool = Executors.newFixedThreadPool(10);
  • core = max = 10。
  • 队列:LinkedBlockingQueue(无界)。
  • 固定线程数,任务排队。

场景:CPU 密集型,线程数 = CPU 核数。

:无界队列,任务多了 OOM。

二、CachedThreadPool

ExecutorService pool = Executors.newCachedThreadPool();
  • core = 0,max = Integer.MAX_VALUE。
  • 队列:SynchronousQueue(不存)。
  • 60 秒空闲回收。
  • 来了任务就开新线程。

场景:IO 密集,短任务。

:线程数无上限,可能创建过多线程 OOM。

三、SingleThreadExecutor

ExecutorService pool = Executors.newSingleThreadExecutor();
  • core = max = 1。
  • 无界队列。
  • 单线程串行执行。

场景:需要顺序执行的任务。

:无界队列 OOM。

四、ScheduledThreadPool

ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
pool.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
  • 定时/周期任务。
  • DelayedWorkQueue。

场景:定时任务(替代 Timer)。

五、对比

线程池 核心 最大 队列 场景
Fixed n n 无界 CPU 密集
Cached 0 Synchronous IO 密集
Single 1 1 无界 顺序执行
Scheduled n Delayed 定时任务

六、生产建议

不要用 Executors,手动 new ThreadPoolExecutor:

ThreadPoolExecutor pool = new ThreadPoolExecutor(
    10, 20, 60, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(100),
    new ThreadFactoryBuilder().setNameFormat("biz-pool-%d").build(),
    new ThreadPoolExecutor.CallerRunsPolicy()
);

原因: - 明确有界队列,避免 OOM。 - 明确最大线程数。 - 自定义线程名,方便排查。 - 明确拒绝策略。

七、线程数怎么设

  • CPU 密集:核数 + 1。
  • IO 密集:核数 × (1 + 等待时间/计算时间)。
  • 实际压测调优。

阿里规约

线程池不允许用 Executors,要用 ThreadPoolExecutor,明确参数,避免 OOM。