线程池必须手动关闭否则会导致资源泄漏和JVM无法正常退出。Java线程池关闭分为三种情况:优雅关闭shutdown()会执行完队列任务,强制关闭shutdownNow()立即停止所有任务,超时控制awaitTermination()限定关闭时间。区别在于shutdown()保证任务完成但耗时,shutdownNow()快速但可能丢失任务,awaitTermination()可设置等待时间。Spring中使用@Async需配置destroyMethod,线上环境要监控线程状态防止内存泄漏。面试常考线程池关闭机制,正确处理中断信号是关键,关闭后线程池不可重启需新建实例。
📦 2025年Java面试宝典网盘地址:
🔵 链接
提取码:9b3g
必须手动关闭! 很多新手觉得线程池用完就不用管了,这是大错特错!想象一下面试场景:面试官问完你线程池参数配置,突然追问:“线程池用完怎么处理?” 如果你回答“不用管”,基本就凉了。
为什么必须手动关闭线程池?
allowCoreThreadTimeOut),持续占用内存举个真实案例:我们线上有个服务用了Executors.newCachedThreadPool(),但没手动关闭线程池。运行一周后线程数暴涨到5000+,直接拖垮整个服务器!

ExecutorService executor = Executors.newFixedThreadPool(4);
executor.shutdown(); // 关键代码
适用场景:需要执行完队列中所有任务
特点:
面试应答技巧:
“比如订单结算服务,必须保证所有待处理订单完成结算后才能停机,这时候就该用shutdown()”
List<Runnable> unfinished = executor.shutdownNow();
适用场景:需要立即停止所有任务
特点:
Thread.interrupt())关键区别点:
如果面试官追问:“shutdownNow()一定能立即停止线程吗?” 要回答:
“不一定!如果线程没有正确处理中断信号(比如catch住InterruptedException后继续运行),任务仍会执行完”
executor.shutdown();
if(!executor.awaitTermination(60, TimeUnit.SECONDS)) {
List<Runnable> unfinished = executor.shutdownNow();
}
适用场景:需要限定关闭时间
参数意义:
boolean result = executor.awaitTermination(5, TimeUnit.SECONDS);
Spring中的陷阱
在Spring Boot项目中用@Async时:
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newCachedThreadPool();
}
一定要配置destroyMethod!否则重启应用时旧线程池不会关闭
内存泄漏排查技巧
用jstack检查线程状态:
jstack <pid> | grep 'pool-'
看到大量WAITING状态的线程,基本就是未关闭的线程池
工具类封装建议
写个工具类统一处理:
public static void shutdownPool(ExecutorService pool, int timeoutSec) {
pool.shutdown();
try {
if(!pool.awaitTermination(timeoutSec, TimeUnit.SECONDS)) {
pool.shutdownNow();
}
} catch (InterruptedException e) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}
}
当面试官问:“线程池关闭后还能重新启动吗?”
标准答案:
“不能!ExecutorService关闭后状态不可逆。需要新建线程池实例,就像被销毁的对象不能复活一样。”
若追问:“线程池关闭时任务中断如何处理?”
高分回答:
“分三层处理:
Thread.currentThread().isInterrupted()InterruptedException时调用Thread.currentThread().interrupt()恢复中断状态最后的小福利:准备面试少不了刷题神器!通过 面试鸭返利网 购买面试鸭会员可返利25元,省下的钱还能再买杯咖啡提神~

扫码联系我返利
(当前返利8元,金额随官方实际价格波动,最好提前咨询)

面试鸭小程序码

美团大额优惠券,给自己加个鸡腿吧!

支付宝扫码领取1-8元无门槛红包
