簡體   English   中英

殺死Java Process對象

[英]Killing a Java Process object

我有一個跨平台(Linux和Windows)程序,目前在Java 7上運行。該程序將使用ProcessBuilder啟動一個或多個工作程序作為進程(使用此處的說明):

String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
String classpath = System.getProperty("java.class.path");
String className = MyClass.class.getCanonicalName();

ProcessBuilder pb = new ProcessBuilder(javaBin, "-cp", classpath, className);
pb.directory(null);
pb.inheritIO();

Process p = pb.start();

這種方法的原因旨在解決舊系統的問題,該系統以線程運行工作程序。 但是,由於我們正在運行的代碼的性質,工作人員可能會進入一個他們不會退出的循環。 由於Java不支持終止線程的想法,我們在假設Java實際上可以殺死進程的情況下轉移到一個完全獨立的進程。

然而,在Java 7中似乎並非如此 - Process.destroy()發送SIGTERM,而不是SIGKILL,而我們陷入困境的工作人員並沒有像我們期望的那樣被殺死。 Java 8實現了Process.destroyForcibly(),它可以解決問題,但升級核心Java版本可能會引入一些錯誤,如果可能的話,升級是我們想要避免的。

大多數其他解決方案涉及反映到UNIXProcess類,獲取pid,並將kill命令傳遞給shell。 但是,這對我們來說不起作用,因為我們在Windows上運行,其中Process沒有任何pid的掌握,並且進一步迫使我們包括特定於操作系統的代碼路徑,這是非常不受歡迎的。

是否有一些可靠的方法讓Java終止某些東西?

您可以嘗試此API SIGAR

示例代碼:

final Sigar sigar = new Sigar();
final long[] processes = sigar.getProcList();

for (final long processId : processes) {
    System.out.println(processId + " = " + ProcUtil.getDescription(sigar, processId));
    final String processDescription = ProcUtil.getDescription(sigar, processId);

    if(processDescription.contains("notepad.exe")){
        System.out.println("Found notepad.exe with id [" + processId + "] - KILLING IT!");
        sigar.kill(processId, -9);
    }
}

代碼來源: 鏈接

在我的情況下,因為我正在編寫父進程和子進程,所以解決方案是添加一個停止JVM的ShutdownHook(一個簡單的System.exit(1)是不夠的):

Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            Runtime.getRuntime().halt(5);
        }
});

在此之后,當收到SIGTERM時,進程將終止,就像它已由父進程發送SIGKILL一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM