我正在使用Java ProcessBuilder(JDK 8)。 该过程如下所示。
public Process createProcess(RunnableImplementation runnableImplementation) throws IOException {
String command = runnableImplementation.command();
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(new File(runnableImplementation.executionFolderPath()));
processBuilder.command("cmd.exe", "/c", command);
processBuilder.redirectErrorStream(true);
//global var
process = processBuilder.start();
return process;
}
我的命令执行一个Ruby脚本,该脚本执行其他Ruby脚本。 当我尝试停止创建的进程时,至少我希望父进程被停止,但事实并非如此。这使我感到困惑,因为以下方法返回true。
public boolean killProcess() {
System.out.println("Trying to stop the running process, this can take a while");
boolean success = false;
if (process != null && process.isAlive()) {
//global var
process.destroyForcibly();
try {
success = process.waitFor(5, TimeUnit.MINUTES);
System.out.println("The process was successfully stopped");
} catch (Exception e) {
e.printStackTrace();
System.out.println("Waiting for the process to stop was interrupted, it is no longer possible to ensure that all subprocesses are stopped cleanly");
}
} else {
System.out.println("Nothing to stop");
}
return success;
}
Process类中的waitFor方法。
/**
* Causes the current thread to wait, if necessary, until the
* subprocess represented by this {@code Process} object has
* terminated, or the specified waiting time elapses.
*
* <p>If the subprocess has already terminated then this method returns
* immediately with the value {@code true}. If the process has not
* terminated and the timeout value is less than, or equal to, zero, then
* this method returns immediately with the value {@code false}.
*
* <p>The default implementation of this methods polls the {@code exitValue}
* to check if the process has terminated. Concrete implementations of this
* class are strongly encouraged to override this method with a more
* efficient implementation.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if the subprocess has exited and {@code false} if
* the waiting time elapsed before the subprocess has exited.
* @throws InterruptedException if the current thread is interrupted
* while waiting.
* @throws NullPointerException if unit is null
* @since 1.8
*/
public boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
long startTime = System.nanoTime();
long rem = unit.toNanos(timeout);
do {
try {
exitValue();
return true;
} catch(IllegalThreadStateException ex) {
if (rem > 0)
Thread.sleep(
Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
}
rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
} while (rem > 0);
return false;
}
为什么我知道该过程没有停止: 如果通过Windows Cmd启动Ruby进程,则可以看到两个Ruby进程的外观(Windows任务管理器)-如果关闭Cmd窗口或按ctrl + c,它们将消失。当我通过Java启动脚本并执行killProcess方法时,它们不会消失,我必须手动停止它们。
我想停止主流程及其所有子流程,该怎么办?我考虑过跟踪PID。