在 Java 中终止进程的正确方法

The right way to kill a process in Java

在 Java 中终止进程的最佳方法是什么?

获取 PID 然后用 Runtime.exec() 杀死它 ?

使用destroyForcibly()

这两种方法有什么区别,还有其他解决方法吗?

如果您要终止的进程已被您的应用程序启动

那么您可能有对它的引用(ProcessBuilder.start()Runtime.exec() 都是 return 引用)。在这种情况下,您可以简单地调用 p.destroy()。我认为这是最干净的方法(但要小心:由 p 启动的子流程可能会继续存在,请查看 Process.destroy does not kill multiple child processes 了解更多信息)。

仅当 destroy() 在特定超时后失败时才应使用 destroyForcibly。一言以蔽之

  1. 终止进程 destroy()
  2. 允许进程以合理的超时从容退出
  3. 如果进程还活着,用destroyForcibly()杀死它

如果你想杀死的进程是外部的

那么你没有太多选择:你需要通过OS API (Runtime.exec)。在 Windows 上,要调用的程序将是 taskkill.exe,而在 Mac 和 Linux 上,您可以尝试 kill.


查看 Support for Process.destroyForcibly() and .isAlive() from Java 8 and Killing a process using Java and Code a Simple Java App to Kill Any Process After a Specified Time 了解更多信息。

如果您试图终止您的 java 代码启动的主进程,我建议您使用 System.exit()。好处在这里解释:when should we call system exit in java.

本质上,System.exit() 将 运行 关闭挂钩,这些挂钩将确保在您的进程被杀死之前,任何可能尚未完成其工作的相关非守护进程被杀死。这是干净的方法。

如果进程不是您的,您将不得不依赖操作系统为您完成这项工作,如以下答案中所述:Killing a Process Using Java

在这种情况下,您建议 Runtime.exec() 在 *nix 上击杀是一个不错的选择。

现在至于 destroyForcibly(),您通常会在您的 java 代码生成的子进程上调用它,该代码可能是从进程 api 的 ProcessBuilder.start()Runtime.exec()

对我有用的是 System.exit(0); 它工作得很好,因为它关闭了所有仍然 运行 的进程和组件

中java8源代码

public Process destroyForcibly() {
    destroy();
    return this;
}

我只想说 destroyForcibly 等于 Java 中的 destroy 8.
因此,如果在调用 destroy 方法后进程仍然存在,则应尝试通过 pid 终止进程。 如果你在java 9+,你可以很容易地得到pid,只需调用Process.pid()方法。

Java 9介绍ProcessHandle that exposes .destroy() and .destroyForcibly()方法。

TL;DR:

如果您知道进程 ID (pid),请使用 .of:

ProcessHandle.of(pid).destroy();

否则,使用 ProcessHandle.allProcesses(), inspect them with .info() 列出 运行 个进程并使用其中一种 destroy 方法。