Java线程池 #
一、线程池概述 #
1.1 为什么使用线程池 #
- 减少线程创建销毁开销
- 控制并发数量
- 提供任务队列和拒绝策略
- 便于管理线程
1.2 线程池体系 #
text
Executor
└── ExecutorService
├── ThreadPoolExecutor
│ └── ScheduledThreadPoolExecutor
└── ForkJoinPool
二、ThreadPoolExecutor #
2.1 创建线程池 #
java
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(100), // 任务队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
2.2 参数详解 #
| 参数 | 说明 |
|---|---|
| corePoolSize | 核心线程数,常驻线程 |
| maximumPoolSize | 最大线程数 |
| keepAliveTime | 空闲线程存活时间 |
| unit | 时间单位 |
| workQueue | 任务队列 |
| threadFactory | 线程工厂 |
| handler | 拒绝策略 |
2.3 执行流程 #
text
1. 线程数 < corePoolSize → 创建新线程
2. 线程数 = corePoolSize → 加入队列
3. 队列满 → 创建新线程直到maximumPoolSize
4. 线程数 = maximumPoolSize → 执行拒绝策略
2.4 拒绝策略 #
java
// AbortPolicy:抛异常(默认)
new ThreadPoolExecutor.AbortPolicy();
// CallerRunsPolicy:调用者执行
new ThreadPoolExecutor.CallerRunsPolicy();
// DiscardPolicy:丢弃任务
new ThreadPoolExecutor.DiscardPolicy();
// DiscardOldestPolicy:丢弃最老任务
new ThreadPoolExecutor.DiscardOldestPolicy();
三、Executors工厂方法 #
3.1 FixedThreadPool #
java
ExecutorService executor = Executors.newFixedThreadPool(5);
// 固定线程数,无界队列
// corePoolSize = maximumPoolSize = n
3.2 CachedThreadPool #
java
ExecutorService executor = Executors.newCachedThreadPool();
// 可缓存线程池,线程数无限
// corePoolSize = 0, maximumPoolSize = Integer.MAX_VALUE
3.3 SingleThreadExecutor #
java
ExecutorService executor = Executors.newSingleThreadExecutor();
// 单线程执行器
// corePoolSize = maximumPoolSize = 1
3.4 ScheduledThreadPool #
java
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
// 延迟执行
scheduler.schedule(() -> {
System.out.println("延迟1秒执行");
}, 1, TimeUnit.SECONDS);
// 定期执行
scheduler.scheduleAtFixedRate(() -> {
System.out.println("每2秒执行");
}, 0, 2, TimeUnit.SECONDS);
3.5 注意事项 #
java
// 不推荐使用Executors创建线程池
// 1. FixedThreadPool和SingleThreadExecutor使用无界队列,可能OOM
// 2. CachedThreadPool线程数无限,可能OOM
// 推荐:手动创建ThreadPoolExecutor
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 10, 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000)
);
四、提交任务 #
4.1 execute #
java
executor.execute(() -> {
System.out.println("执行任务");
});
4.2 submit #
java
Future<?> future1 = executor.submit(() -> {
System.out.println("执行任务");
});
Future<Integer> future2 = executor.submit(() -> {
return 100;
});
try {
Integer result = future2.get();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
4.3 invokeAll #
java
List<Callable<Integer>> tasks = Arrays.asList(
() -> 1,
() -> 2,
() -> 3
);
List<Future<Integer>> futures = executor.invokeAll(tasks);
4.4 invokeAny #
java
Integer result = executor.invokeAny(tasks); // 返回第一个完成的结果
五、关闭线程池 #
5.1 shutdown #
java
executor.shutdown(); // 平滑关闭,等待任务完成
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow(); // 强制关闭
}
5.2 shutdownNow #
java
List<Runnable> notExecuted = executor.shutdownNow(); // 立即关闭
// 返回未执行的任务列表
5.3 判断状态 #
java
executor.isShutdown(); // 是否已关闭
executor.isTerminated(); // 是否已终止
六、线程池监控 #
java
ThreadPoolExecutor executor = new ThreadPoolExecutor(...);
// 监控信息
executor.getActiveCount(); // 活动线程数
executor.getCompletedTaskCount(); // 已完成任务数
executor.getQueue().size(); // 队列大小
executor.getPoolSize(); // 当前线程数
executor.getCorePoolSize(); // 核心线程数
executor.getMaximumPoolSize(); // 最大线程数
七、线程池配置建议 #
7.1 CPU密集型 #
java
// CPU核心数 + 1
int cores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
cores + 1, cores + 1, 0L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>()
);
7.2 IO密集型 #
java
// CPU核心数 * 2
int cores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
cores * 2, cores * 2, 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>()
);
7.3 混合型 #
根据IO等待时间占比调整。
八、总结 #
| 线程池 | 特点 |
|---|---|
| FixedThreadPool | 固定线程数 |
| CachedThreadPool | 可缓存,线程数无限 |
| SingleThreadExecutor | 单线程 |
| ScheduledThreadPool | 支持定时任务 |
线程池要点:
- 推荐手动创建ThreadPoolExecutor
- 合理配置核心线程数和最大线程数
- 选择合适的任务队列
- 正确关闭线程池
最后更新:2026-03-26