线程池 shutdown() 和 shutdownNow() 完整对比
共同点
拒绝新任务:两者调用后都会立即拒绝新提交的任务,抛出
RejectedExecutionException
非阻塞调用:两个方法都会立即返回,不会等待所有任务结束
触发关闭流程:都会使线程池开始关闭过程,最终目标是达到
TERMINATED
状态
核心区别
中断机制详解
shutdown()
的中断机制
只中断空闲线程:调用
interruptIdleWorkers()
目的:
释放空闲线程占用的系统资源
加速线程池的完全终止过程
让空闲线程检测到关闭信号并退出
不中断正在执行任务的线程:确保任务能够完成
shutdownNow()
的中断机制
中断所有线程:调用
interruptWorkers()
目的:尽快停止所有活动,包括正在执行的任务
不保证任务停止:任务需自行处理中断信号
拒绝新任务的机制
在两种方法中,拒绝新任务都是通过改变线程池状态实现的:
状态从
RUNNING
变为SHUTDOWN
或STOP
在这些状态下,
execute()
和submit()
方法会直接拒绝新任务与工作线程是否被中断无关
使用场景
shutdown()
:需要所有已提交任务都能完成
有足够时间等待任务执行
需要优雅关闭
shutdownNow()
:需要紧急停止
需要获取未执行任务列表
资源紧张,不能等待所有任务完成
最佳实践
executorService.shutdown();
try {
if (!executorService.awaitTermination(timeout, TimeUnit.SECONDS)) {
List<Runnable> unfinishedTasks = executorService.shutdownNow();
System.out.println("线程池强制关闭,剩余未执行任务数: " + unfinishedTasks.size());
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
总结
shutdown()
和 shutdownNow()
的本质区别在于对任务和线程的处理策略:shutdown()
更温和,保证任务完成;shutdownNow()
更激进,优先释放资源。两者都拒绝新任务,但通过不同的中断机制和任务处理方式来实现线程池的关闭。
License:
CC BY 4.0