如何优雅的关闭线程池?
【摘要】 嗨,你好呀,我是猿java在 Java的线程池管理中,shutdown()和shutdownNow()是用于关闭线程池的两种方法,尽管都是为了关闭线程池,但它们存在显著差异。这篇文章,我们将详细阐述它们的工作原理。 1. shutdown()shutdown()的使用方式如下所示:ExecutorService executor = Executors.newFixedThreadPool(...
嗨,你好呀,我是猿java
在 Java的线程池管理中,shutdown()和shutdownNow()是用于关闭线程池的两种方法,尽管都是为了关闭线程池,但它们存在显著差异。这篇文章,我们将详细阐述它们的工作原理。
1. shutdown()
shutdown()的使用方式如下所示:
ExecutorService executor = Executors.newFixedThreadPool(3);
...
executor.shutdown();
shutdown()的工作原理:
shutdown()方法的主旨是指示线程池进入“关闭状态”,即线程池不再接受新任务请求。- 任何已经提交的任务,包括那些在等待执行队列中的任务,会继续执行,直到所有任务完成后线程池完全停止。
- 调用
shutdown()后,线程池的状态变为"SHUTDOWN",但不会中断正在执行的任务。
通过 shutdown() 关闭线程池,所有正在处理的任务和已提交的任务库将正常完成,不会有半途被终止的情况发生。
shutdown()的特点:
- 平滑停止:调用后线程池会拒绝新任务,但不会强制停止已提交和正在运行的任务。从这种意义上来说,
shutdown()提供了一种平稳的关闭方式。 - 阻塞等待的任务会正常执行:那些已经正式提交但还没被执行的任务仍在等待队列中,可以继续被线程池拾取和处理。
- 等待线程自行完成任务:只要所有任务完成后,线程池就会完全停止。
shutdown()的 注意事项
shutdown()不会立即终止线程池,而是等待所有已经提交的任务(包括正在执行的和在任务队列中的)完成。- 如果你需要检查线程池是否已关闭,可以使用如下方法:
isShutdown():如果已经调用了shutdown(),返回true。isTerminated():如果线程池完全停止了,所有任务都已经完成或中止,返回true。
通过 shutdown() 关闭的线程池不会突然地停止任务,这在一些长时间处理数据或大批量任务的场景中尤为重要。
2. shutdownNow()
shutdownNow()的用法如下代码:
ExecutorService executor = Executors.newFixedThreadPool(3);
...
executor.shutdownNow();
shutdownNow()的工作原理:
shutdownNow()会立即尝试停止所有正在执行的任务,并返回尚未执行的任务列表。- 线程池会调用每个线程的
interrupt()函数来尝试停止它们。 - 和
shutdown()不同,shutdownNow()是一个“强制式”的关闭方式。在调用后,线程池会试图中断当前所有正在执行的任务,并返回那些还没来得及执行的任务。
shutdownNow()的特点:
- 强制终止:
shutdownNow()不只是停止接收新任务,还会中断当前正在执行的任务以及移除队列中还未执行的任务。 - 返回未开始的任务:它会返回哪些任务没有被执行,还在任务队列里等待,而这些任务不再会被执行。
- 潜在的任务中断:
shutdownNow()实际上通过Thread.interrupt()方法来尝试终止正在执行的任务。因此,如果任务没有处理好中断操作(即不考虑线程的中断状态),某些正在执行的任务可能不会及时终止。
3. 两者对比
接收新任务
shutdown():此方法调用后,线程池不再接受任何新的任务请求。任务队列中已经被提交的任务会继续执行。shutdownNow():此方法调用后,线程池立即拒绝新任务,同时会尝试中断当前运行中的任务。
执行已提交的任务
shutdown():不再受理新的任务提交,已提交而尚未执行的任务会继续执行直到正常完成。shutdownNow():会尝试中断正在运行的任务,并返回那些还未被执行的任务列表。
对线程的影响
shutdown():等待所有线程完成,线程池逐渐关闭。shutdownNow():粗暴地尝试中断所有线程,线程可能会在处理中途中断并无法完成任务。
线程中断
shutdown():不主动中断任何线程。shutdownNow():主动中断线程。
4. 总结
本文我们分析了shutdown() 和 shutdownNow()的原理以及它们之间的差异,两者都是用于关闭 Java的线程池,是一个比简单的知识点,在实际工作中,我们一般很少主动去关闭线程池,但是如果工作中真的存在关闭线程池的需求,掌握两个方法对我们会有很大的帮助。
5. 交流学习
最后,把猿哥的座右铭送给你:投资自己才是最大的财富。 如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注公众号:猿java,持续输出硬核文章。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)