Executors类创建线程池的静态方法详解
提供了便捷的线程池创建方法,但在生产环境中,建议手动创建 。 ,以便更好地控制线程池参数,避免潜在的内存和性能问题。负载较重的服务器,控制并发数。大量短时异步任务,弹性伸缩。顺序执行任务,保证顺序性。计算密集型任务,并行处理。定时任务,周期性任务。
并发是Java进阶的分水岭,也是拉开薪资差距的核心能力。
为了帮大家避开碎片化学习误区,我整理了一套
《Java并发编程实战》视频课
覆盖线程基础、JMM底层、锁机制、JUC工具、线程池、并发设计模式与线上实战。
全程原理+源码+实战+调优一站式打通,零基础也能轻松吃透Java并发,彻底摆脱技术瓶颈。
Executors 类提供了多种创建线程池的静态方法,主要分为以下几类:
1. 固定大小线程池
// 创建固定大小的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(int nThreads);
特点:
- 核心线程数 = 最大线程数 = nThreads
- 使用无界队列(LinkedBlockingQueue)
- 线程空闲时不会被回收
- 适合负载较重的服务器
2. 单线程线程池
// 创建单线程的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
特点:
- 只有一个工作线程
- 保证任务按顺序执行
- 使用无界队列
- 适合需要顺序执行任务的场景
3. 缓存线程池
// 创建可缓存的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
特点:
- 核心线程数 = 0,最大线程数 = Integer.MAX_VALUE
- 使用同步队列(SynchronousQueue)
- 空闲线程60秒后回收
- 适合大量短时异步任务
4. 定时/周期线程池
// 创建定时任务线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(int corePoolSize);
特点:
- 可以执行定时任务和周期性任务
- 使用延迟队列(DelayedWorkQueue)
- 适合定时任务场景
5. 工作窃取线程池(Java 8+)
// 创建工作窃取线程池(ForkJoinPool)
ExecutorService workStealingPool = Executors.newWorkStealingPool();
// 或指定并行级别
ExecutorService workStealingPool = Executors.newWorkStealingPool(int parallelism);
特点:
- 基于 ForkJoinPool 实现
- 使用工作窃取算法,提高CPU利用率
- 适合计算密集型任务
详细对比表格
|
方法 |
核心线程数 |
最大线程数 |
队列类型 |
线程存活时间 |
适用场景 |
|
newFixedThreadPool |
nThreads |
nThreads |
LinkedBlockingQueue |
无限 |
负载较重的服务器,控制并发数 |
|
newSingleThreadExecutor |
1 |
1 |
LinkedBlockingQueue |
无限 |
顺序执行任务,保证顺序性 |
|
newCachedThreadPool |
0 |
Integer.MAX_VALUE |
SynchronousQueue |
60秒 |
大量短时异步任务,弹性伸缩 |
|
newScheduledThreadPool |
corePoolSize |
Integer.MAX_VALUE |
DelayedWorkQueue |
无限 |
定时任务,周期性任务 |
|
newWorkStealingPool |
CPU核心数 |
无限制 |
内部队列 |
无限 |
计算密集型任务,并行处理 |
代码示例
import java.util.concurrent.*;
public class ExecutorsDemo {
public static void main(String[] args) {
// 1. 固定大小线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
// 2. 单线程线程池
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
// 3. 缓存线程池
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 4. 定时线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
// 5. 工作窃取线程池
ExecutorService workStealingPool = Executors.newWorkStealingPool();
// 使用示例
fixedPool.execute(() -> System.out.println("FixedThreadPool任务"));
scheduledPool.schedule(() -> {
System.out.println("3秒后执行");
}, 3, TimeUnit.SECONDS);
// 关闭线程池
fixedPool.shutdown();
singleThreadPool.shutdown();
cachedPool.shutdown();
scheduledPool.shutdown();
workStealingPool.shutdown();
}
}
潜在问题与注意事项
1. 内存溢出风险
// 以下两种方式使用无界队列,可能导致OOM
ExecutorService fixedPool = Executors.newFixedThreadPool(10);
ExecutorService singlePool = Executors.newSingleThreadExecutor();
// 缓存线程池可能创建过多线程导致OOM
ExecutorService cachedPool = Executors.newCachedThreadPool();
2. 推荐手动创建线程池
// 更推荐的方式:手动创建ThreadPoolExecutor
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(100), // 有界队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
3. 阿里巴巴开发规范建议
根据《阿里巴巴Java开发手册》:
- 线程池不允许使用
Executors 创建 - 推荐使用
ThreadPoolExecutor 构造函数创建 - 原因:规避资源耗尽风险
4. 选择合适的拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 10, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadPoolExecutor.AbortPolicy() // 默认:抛出异常
// new ThreadPoolExecutor.CallerRunsPolicy() // 调用者运行
// new ThreadPoolExecutor.DiscardOldestPolicy() // 丢弃最老任务
// new ThreadPoolExecutor.DiscardPolicy() // 直接丢弃
);
总结
虽然 Executors 提供了便捷的线程池创建方法,但在生产环境中,建议手动创建 ThreadPoolExecutor ,以便更好地控制线程池参数,避免潜在的内存和性能问题。
简单记忆:
-
Fixed:固定大小,无界队列 -
Single:单线程,顺序执行 -
Cached:弹性伸缩,短时任务 -
Scheduled:定时任务 -
WorkStealing:工作窃取,并行计算
并发是Java进阶的分水岭,也是拉开薪资差距的核心能力。
为了帮大家避开碎片化学习误区,我整理了一套
《Java并发编程实战》视频课
覆盖线程基础、JMM底层、锁机制、JUC工具、线程池、并发设计模式与线上实战。
全程原理+源码+实战+调优一站式打通,零基础也能轻松吃透Java并发,彻底摆脱技术瓶颈。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)