我有一个跨平台(Linux和Windows)的程序,目前运行在Java 7上。该程序将使用ProcessBuilder启动一个或多个worker进程(使用这里的指令):
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终止某些东西?