程池
程池复用线程,避免频繁创建销毁,提高性能和资源利用率。
Executors 工厂方法
Java
// 固定大小线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
// 缓存线程池(按需创建,空闲回收)
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 单线程池(顺序执行)
ExecutorService singlePool = Executors.newSingleThreadExecutor();
// 定时任务线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
Executors 问题:生产环境不建议直接用 Executors,FixedThreadPool 和 SingleThreadExecutor 任务队列无界可能导致 OOM。
ThreadPoolExecutor 核心参数
Java
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, // 核心线程数(常驻)
maximumPoolSize, // 最大线程数
keepAliveTime, // 非核心线程空闲存活时间
TimeUnit.SECONDS, // 时间单位
workQueue, // 任务队列
threadFactory, // 程工厂(可选)
handler // 拒绝策略(可选)
);
参数详解
| 参数 | 说明 |
|---|---|
| corePoolSize | 核心线程数,常驻不回收 |
| maximumPoolSize | 最大线程数,任务多时临时扩展 |
| keepAliveTime | 非核心线程空闲存活时间 |
| workQueue | 任务队列,等待执行的任务 |
| handler | 拒绝策略,队列满时处理新任务 |
任务队列类型
| 队列类型 | 特点 |
|---|---|
| ArrayBlockingQueue | 有界队列,防止 OOM |
| LinkedBlockingQueue | 可选有界,默认无界 |
| SynchronousQueue | 无缓冲,直接传递 |
拒绝策略
| 策略 | 说明 |
|---|---|
| AbortPolicy | 抛 RejectedExecutionException(默认) |
| CallerRunsPolicy | 由调用线程执行 |
| DiscardPolicy | 直接丢弃 |
| DiscardOldestPolicy | 丢弃最老任务,尝试重新提交 |
程池执行流程
Java
提交任务 → 核心线程数未满? → 创建核心线程执行
↓ 满
加入任务队列 → 队列未满? → 等待核心线程执行
↓ 满
创建非核心线程 → 未达最大? → 执行任务
↓ 达到最大
执行拒绝策略
推荐配置
Java
// 生产环境推荐配置
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心 5 个
10, // 最大 10 个
60, TimeUnit.SECONDS, // 空闲 60 秒回收
new ArrayBlockingQueue<>(100), // 有界队列,容量 100
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
配置原则
- CPU 密集型:核心线程数 ≈ CPU 核数 + 1
- IO 密集型:核心线程数 ≈ CPU 核数 × 2
- 有界队列:防止任务堆积导致 OOM
- 合理拒绝策略:记录日志或降级处理
程池使用示例
submit 提交任务
Java
executor.submit(() -> {
// 执行任务
});
// submit 返回 Future,可获取结果
Future<String> future = executor.submit(() -> "结果");
String result = future.get();
execute 提交任务
Java
executor.execute(() -> {
// 执行任务,无返回值
});
批量提交
Java
List<Callable<String>> tasks = Arrays.asList(
() -> "task1",
() -> "task2",
() -> "task3"
);
List<Future<String>> futures = executor.invokeAll(tasks);
for (Future<String> future : futures) {
System.out.println(future.get());
}
程池关闭
Java
// 平滑关闭:不再接受新任务,等待现有任务完成
executor.shutdown();
// 立即关闭:尝试中断所有任务
List<Runnable> unfinished = executor.shutdownNow();
// 等待关闭完成
executor.awaitTermination(60, TimeUnit.SECONDS);
// 判断状态
executor.isShutdown(); // 是否已调用 shutdown
executor.isTerminated(); // 是否所有任务已完成
ScheduledExecutorService 定时任务
text
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// 延迟执行
scheduler.schedule(() -> {
System.out.println("延迟 5 秒执行");
}, 5, TimeUnit.SECONDS);
// 固定延迟(任务完成后延迟 n 秒再执行)
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("执行");
}, 0, 3, TimeUnit.SECONDS);
// 固定频率(不管任务是否完成,每隔 n 秒执行)
scheduler.scheduleAtFixedRate(() -> {
System.out.println("执行");
}, 0, 3, TimeUnit.SECONDS);
要点总结
- 程池复用线程,避免创建销毁开销
- 生产环境不建议直接用 Executors
- 核心参数:corePoolSize、maximumPoolSize、workQueue、handler
- CPU 密集型:线程数 ≈ CPU核数 + 1
- IO 密集型:线程数 ≈ CPU核数 × 2
- 必须使用有界队列防止 OOM
- shutdown() 平滑关闭,shutdownNow() 立即关闭
- ScheduledExecutorService 执行定时任务
📝 发现内容有误?点击此处直接编辑