讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java中如何实现线程池的优雅关闭_Java并发编程中的资源管理解析

云磊吖_3496

云磊吖_3496

发布时间:2026-02-09 14:11:18

|

556人浏览过

|

来源于php中文网

原创

shutdown() 通知线程池不再接受新任务但继续执行已提交和运行中任务;shutdownNow() 尝试中断正在执行的任务、清空队列并返回未执行任务列表,实际终止效果依赖任务是否响应中断。

在java中如何实现线程池的优雅关闭_java并发编程中的资源管理解析

shutdown() 和 shutdownNow() 的本质区别

调用 shutdown() 是通知线程池:不再接受新任务,但会继续执行已提交的队列中任务和正在运行的任务;shutdownNow() 则是尝试中断所有正在执行的任务,并清空任务队列,返回尚未执行的任务列表。

常见错误是误以为 shutdownNow() 能立即终止所有任务——实际能否真正停止,取决于任务本身是否响应中断(即是否检查 Thread.interrupted() 或捕获 InterruptedException)。

  • shutdown() 后需配合 awaitTermination(long, TimeUnit) 等待自然结束,否则主线程可能提前退出
  • shutdownNow() 返回的 List<runnable></runnable> 是被丢弃的任务,需自行决定是否重试或记录
  • 若任务中使用了阻塞 I/O(如 SocketInputStream.read()),中断不会生效,必须配合超时或可关闭的资源(如 Socket.close())

如何确保 awaitTermination 不无限等待

awaitTermination() 是阻塞调用,若超时时间设为过长(如 Long.MAX_VALUE),或任务陷入死循环/无响应状态,会导致关闭流程卡死。

建议始终设置合理超时(如 30 秒),并在超时后根据业务容忍度决策:

立即学习“Java免费学习笔记(深入)”;

Java注释规范Skills
Java注释规范Skills

当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。

下载
  • 日志记录未完成任务数:pool.getCompletedTaskCount() 和 pool.getTaskCount() 可辅助判断积压程度
  • 对关键任务,可在 Runnable 中嵌入超时逻辑(如用 Future.get(timeout, unit) 包裹实际工作)
  • 避免在任务中使用不可中断的 wait/sleep 替代方案(如用 LockSupport.parkNanos() 并定期检查中断)

守护线程池与 JVM 退出的关系

默认创建的 ThreadPoolExecutor 使用非守护线程,JVM 不会因主线程结束而退出,直到所有工作线程自然终止。这容易造成“程序看似结束,实则后台线程仍在跑”的假象。

若线程池仅用于短期辅助任务(如日志异步刷盘、监控上报),可考虑自定义 ThreadFactory 将线程设为守护线程:

new ThreadPoolExecutor(1, 1,
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<>(),
    r -> {
        Thread t = new Thread(r);
        t.setDaemon(true); // 关键:设为守护线程
        return t;
    })

注意:守护线程会在 JVM 退出时被强制终止,不保证执行完最后一步(如 flush 缓存、释放锁),因此**不能用于需要强一致性的资源清理场景**。

Spring 环境下 @PreDestroy 的典型陷阱

在 Spring Bean 中用 @PreDestroy 注解调用 shutdown() 很常见,但容易忽略两个关键点:

  • 若线程池是通过 @Bean 创建且作用域为 singleton,默认由 Spring 管理生命周期;但若手动 new 出来(如在构造器中初始化),@PreDestroy 不会触发
  • Spring 容器关闭时,多个 Bean 的销毁顺序不确定,若线程池依赖其他 Bean(如数据库连接池),可能在依赖项已关闭后才执行 shutdown,导致任务失败却无日志
  • 更稳妥的做法是:在 @PreDestroy 中先调用 shutdown(),再用 awaitTermination() 等待,但必须加 try-catch 处理 InterruptedException,并恢复中断状态(Thread.currentThread().interrupt())

真正难处理的,不是关不关得掉,而是关的时候有没有人还在往里 submit 新任务——生产环境常因监听器、回调、定时任务残留导致关闭后仍有任务进入队列。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

2711

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

497

2026.01.26

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4418

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

563

2025.12.01

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2865

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

4041

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

3211

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

1007

2023.09.05

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

20

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn