如何优雅地关闭线程池?(关闭线程的方法)

createh52个月前 (02-01)技术教程12

在 Java的线程池管理中,shutdown()shutdownNow()是用于关闭线程池的两种方法,尽管都是为了关闭线程池,但它们存在显著差异。这篇文章,我们将详细阐述它们的工作原理。

shutdown()

shutdown()的使用方式如下所示:

ExecutorService executor = Executors.newFixedThreadPool(3);
...
executor.shutdown();

shutdown()的工作原理:

  • shutdown() 方法的主旨是指示线程池进入“关闭状态”,即线程池不再接受新任务请求。
  • 任何已经提交的任务,包括那些在等待执行队列中的任务,会继续执行,直到所有任务完成后线程池完全停止。
  • 调用 shutdown() 后,线程池的状态变为"SHUTDOWN",但不会中断正在执行的任务。

通过 shutdown() 关闭线程池,所有正在处理的任务和已提交的任务库将正常完成,不会有半途被终止的情况发生。

shutdown()的特点:

  • 平滑停止:调用后线程池会拒绝新任务,但不会强制停止已提交和正在运行的任务。从这种意义上来说,shutdown() 提供了一种平稳的关闭方式。
  • 阻塞等待的任务会正常执行:那些已经正式提交但还没被执行的任务仍在等待队列中,可以继续被线程池拾取和处理。
  • 等待线程自行完成任务:只要所有任务完成后,线程池就会完全停止。

shutdown()的 注意事项

  • shutdown() 不会立即终止线程池,而是等待所有已经提交的任务(包括正在执行的和在任务队列中的)完成。
  • 如果你需要检查线程池是否已关闭,可以使用如下方法:
    • isShutdown():如果已经调用了 shutdown(),返回 true。
    • isTerminated():如果线程池完全停止了,所有任务都已经完成或中止,返回 true。

通过 shutdown() 关闭的线程池不会突然地停止任务,这在一些长时间处理数据或大批量任务的场景中尤为重要。

shutdownNow()

shutdownNow()的用法如下代码:

ExecutorService executor = Executors.newFixedThreadPool(3);
...
executor.shutdownNow();

shutdownNow()的工作原理:

  • shutdownNow() 会立即尝试停止所有正在执行的任务,并返回尚未执行的任务列表。
  • 线程池会调用每个线程的 interrupt() 函数来尝试停止它们。
  • 和 shutdown() 不同,shutdownNow()是一个“强制式”的关闭方式。在调用后,线程池会试图中断当前所有正在执行的任务,并返回那些还没来得及执行的任务。

shutdownNow()的特点:

  • 强制终止:shutdownNow() 不只是停止接收新任务,还会中断当前正在执行的任务以及移除队列中还未执行的任务。
  • 返回未开始的任务:它会返回哪些任务没有被执行,还在任务队列里等待,而这些任务不再会被执行。
  • 潜在的任务中断:shutdownNow() 实际上通过 Thread.interrupt() 方法来尝试终止正在执行的任务。因此,如果任务没有处理好中断操作(即不考虑线程的中断状态),某些正在执行的任务可能不会及时终止。

两者对比

接收新任务

  • shutdown():此方法调用后,线程池不再接受任何新的任务请求。任务队列中已经被提交的任务会继续执行。
  • shutdownNow():此方法调用后,线程池立即拒绝新任务,同时会尝试中断当前运行中的任务。

执行已提交的任务

  • shutdown():不再受理新的任务提交,已提交而尚未执行的任务会继续执行直到正常完成。
  • shutdownNow():会尝试中断正在运行的任务,并返回那些还未被执行的任务列表。

对线程的影响

  • shutdown():等待所有线程完成,线程池逐渐关闭。
  • shutdownNow():粗暴地尝试中断所有线程,线程可能会在处理中途中断并无法完成任务。

线程中断

  • shutdown():不主动中断任何线程。
  • shutdownNow():主动中断线程。

总结

本文我们分析了shutdown()shutdownNow()的原理以及它们之间的差异,两者都是用于关闭 Java的线程池,是一个比简单的知识点,在实际工作中,我们一般很少主动去关闭线程池,但是如果工作中真的存在关闭线程池的需求,掌握两个方法对我们会有很大的帮助。

相关文章

如何优雅地停止Java进程(如何停止java运行)

目录理解停止Java进程的本质应该如何正确地停止Java进程如何注册关闭钩子使用关闭钩子的注意事项信号量机制总结理解停止Java进程的本质我们知道,Java程序的运行需要一个运行时环境,即:JVM,启...

还不理解 Error 和 Exception 吗,看这篇就够了

在 Java 中的基本理念是 结构不佳的代码不能运行,发现错误的理想时期是在编译期间,因为你不用运行程序,只是凭借着对 Java 基本理念的理解就能发现问题。但是编译期并不能找出所有的问题,有一些 N...

使用 kill 命令杀死 java进程,你用对了吗?

原文地址:https://dwz.cn/E88v8sLN作者: 占小狼在本地调试agent相关功能,需要经常性的杀掉Java进程,验证一些极端情况。每次都是本能执行如下步骤jpskill -9rebo...

我的世界:java vs 基岩的11个不同之处!这是,天堂传送门?

《我的世界》基岩版 vs Java版向来不是完全统一的两个版本,最为经典的差异想必也就是为人所熟知的“船”的合成配方了。然而我们今天就来聊一些更为细节的不同之处!1、基岩版的船无法承载掉落物,JAVA...

又一时代结束 甲骨文宣布将弃用Java插件

Java 插件一直被认为是系统不稳定因素的温床,它的时代即将过去。甲骨文公司宣布 Java 插件即将退出历史舞台。Java 插件不会立即死去。它将在下一个版本的 Java 开发工具包中被弃用,然后随着...

经验分享|程序员成功转行IC,我终于不用再吃“青春饭”

近期后台收到了一位同学的私信,转行IC后他的薪资涨了很多,这位同学之前是程序员,经过不断努力成功转行到IC后端。我是西安一所普通的一本毕业,学的是自动化专业,大学跟大多数人一样过得浑浑噩噩,对自己的职...