在同一个 Process 对象上调用 Runtime.getRuntime.exec(commands) 两次

Call Runtime.getRuntime.exec(commands) twice on the same Process object

我有两个不同的命令(在外部 EXE 文件上)由两个字符串数组 command1command2 表示。我想 运行 这两个在同一个线程中顺序。具体来说,第一条命令执行10分钟。如果需要更长的时间,则终止它并 运行 第二个命令。这就是我正在做的。

public class MyRunnable implements Runnable {
    private Process proc;
    private String[] command1;
    private String[] command2;

    public MyRunnable (String[] command1, String[] command2) {
        this.command1 = command1;
        this.command2 = command2;    
    }

    public void run() {
        try {
            proc = Runtime.getRuntime().exec(command1);

            StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
            StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");

            errorGobbler.start();
            outputGobbler.start();

            exitCode = proc.waitFor(10, TimeUnit.MINUTES);
            if (exitCode)
                System.out.println("Model " + modelPath + ": SUCCESSFULLY!");
            else {
                System.out.println("Model " + modelPath + ": TIMED OUT!");
                proc = Runtime.getRuntime().exec(command2);

                StreamGobbler errorGobbler1 = new StreamGobbler(proc.getErrorStream(), "ERROR");
                StreamGobbler outputGobbler1 = new StreamGobbler(proc.getInputStream(), "OUTPUT");

                errorGobbler1.start();
                outputGobbler1.start();

                proc.waitFor(10, TimeUnit.MINUTES);
            }             
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            proc.destroy();
        }
    }
}

StreamGobbler class 我实现的和这里完全一样 www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html 避免了死锁。一般它的作用是让另一个线程处理proc对象的输出流和错误流。

我不确定将两个不同的子流程分配给同一个 Process 对象是否合适。我观察到即使在调用 proc.waitFor(10, TimeUnit.MINUTES) 之后,command1 的进程仍然 运行s,这会在一段时间后在我的计算机上创建大量进程。如何终止第一个命令的进程?我在 CentOS 7 上使用 Java 1.8。

提前致谢。

在您的 if 中,如果您到达 else 语句,则进程已超过超时,因此在将新进程分配给 proc 之前,您必须先终止前一个进程。 proc.destroy()proc.destroyForcibly() 有两种方法,在 proc = Runtime.getRuntime().exec(command2); 之前添加任何 in you else 语句,应该没问题。