如何高效创建Java线程池?
- 后端开发
- 2025-06-18
- 5
线程池的核心优势
- 降低资源开销:复用已创建的线程,避免频繁线程创建/销毁。
- 提高响应速度:任务到达时直接使用空闲线程执行。
- 任务统一管理:支持任务队列、拒绝策略等机制。
创建线程池的两种方式
方式1:通过 Executors 工厂类(快速创建)
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; // 创建固定大小的线程池(推荐常规使用) ExecutorService fixedPool = Executors.newFixedThreadPool(5); // 创建可缓存线程池(适合短时异步任务) ExecutorService cachedPool = Executors.newCachedThreadPool(); // 创建单线程池(保证任务顺序执行) ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); // 创建定时任务线程池 ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
方式2:通过 ThreadPoolExecutor 构造函数(精细控制)
import java.util.concurrent.*; ExecutorService customPool = new ThreadPoolExecutor( 5, // 核心线程数 (corePoolSize) 10, // 最大线程数 (maximumPoolSize) 60L, // 空闲线程存活时间 (keepAliveTime) TimeUnit.SECONDS, // 时间单位 new ArrayBlockingQueue<>(100), // 任务队列 (容量100) Executors.defaultThreadFactory(), // 线程工厂 new ThreadPoolExecutor.AbortPolicy() // 拒绝策略 );
关键参数详解
| 参数 | 说明 |
|---|---|
| corePoolSize | 核心线程数(即使空闲也不会被回收) |
| maximumPoolSize | 最大线程数(当队列满时创建新线程,直到达到此值) |
| keepAliveTime | 非核心线程的空闲存活时间(超时后回收) |
| workQueue | 任务队列(推荐有界队列如 ArrayBlockingQueue,避免OOM) |
| handler | 拒绝策略(当线程和队列都满时的处理方式) |
四种拒绝策略对比
| 策略 | 行为 |
|---|---|
| AbortPolicy (默认) | 抛出 RejectedExecutionException 异常 |
| CallerRunsPolicy | 由提交任务的线程直接执行任务 |
| DiscardPolicy | 静默丢弃新任务,不报错 |
| DiscardOldestPolicy | 丢弃队列中最旧的任务,尝试重新提交新任务 |
使用示例
// 提交任务到线程池 customPool.execute(() -> { System.out.println("Task running by " + Thread.currentThread().getName()); }); // 关闭线程池(需在程序结束时调用) customPool.shutdown(); // 温和关闭(等待执行中的任务) // customPool.shutdownNow(); // 立即关闭(尝试中断所有任务)
最佳实践与注意事项
-
避免使用无界队列
Executors.newFixedThreadPool() 默认使用无界队列 LinkedBlockingQueue,可能导致OOM,推荐:
new ThreadPoolExecutor(n, n, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100));
-
合理设置线程数量
- CPU密集型任务:核心数 = CPU核数 + 1
- I/O密集型任务:核心数 = CPU核数 × 2
-
务必关闭线程池
使用 shutdown() 或 shutdownNow() 防止资源泄漏。

-
监控线程池状态
通过 ThreadPoolExecutor 的方法获取运行状态:
customPool.getActiveCount(); // 活动线程数 customPool.getCompletedTaskCount(); // 已完成任务数
- 简单场景:用 Executors 快速创建(注意无界队列风险)。
- 生产环境:优先选择 ThreadPoolExecutor 自定义参数。
- 关键原则:设置合理线程数、使用有界队列、明确拒绝策略、及时关闭线程池。
引用说明参考 Oracle 官方文档 ThreadPoolExecutor 及《Java并发编程实战》(Brian Goetz 著),遵循阿里巴巴Java开发手册的线程池规约。
