如何关闭ExecutorService
在 Java 中,ExecutorService 不能直接关闭,需要通过调用其提供的关闭方法来优雅或强制停止。常见做法如下:
一、两种关闭方式
✅ 1. 优雅关闭(推荐)
不再接受新任务,等待已有任务执行完成
executorService.shutdown();
- 不再接收新任务
- 已提交的任务会继续执行
- 不会中断正在执行的任务
✅ 2. 立即关闭(强制)
尝试停止正在执行的任务
executorService.shutdownNow();
- 不再接受新任务
- 尝试中断正在执行的任务
- 返回尚未开始执行的任务列表
⚠️ 注意:shutdownNow() 只是“尝试中断”,不保证一定能停止线程
二、推荐的标准关闭方式(最佳实践)
通常结合 awaitTermination 使用:
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
// 等待超时,强制关闭
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt(); // 保留中断状态
}
三、完整示例
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(() -> System.out.println("task"));
executorService.shutdown();
四、常见误区
❌ 直接置为 null
executorService = null; // 错误,不会关闭线程
❌ 只调用 shutdownNow
executorService.shutdownNow(); // 不一定能真正停止任务
五、如何判断线程池是否已关闭?
executorService.isShutdown(); // 是否已调用 shutdown
executorService.isTerminated(); // 是否完全终止
六、总结
| 方法 | 是否接受新任务 | 是否等待任务完成 | 是否中断 |
|---|---|---|---|
| shutdown | ❌ | ✅ | ❌ |
| shutdownNow | ❌ | ❌ | ✅ |
| shutdown + awaitTermination | ❌ | ✅(可超时) | 可选 |
如果你有 Spring 环境 / 定时任务 / 线程池类型(Fixed / Cached / Scheduled),可以告诉我,我可以给你更具体的关闭方案。