6

这应该很简单,但我在JavaDocs中看不到任何帮助。

我需要的是从我的 Java 代码运行一些外部进程,然后能够监视该进程是否已关闭。换句话说,我希望能够可靠地确定我的外部进程是否未被用户结束。

如果不存在跨平台解决方案,我将接受任何在 Linux 下工作的东西。

我当前的代码片段:

public static void main(String[] args) {
    ProcessBuilder pb = new ProcessBuilder("some proces name");

    try {
        Process p = pb.start();
        // p.isRunning(); <- now, that would be helpful :-)
    } catch (IOException e) {
        e.printStackTrace();
    }
}
4

3 回答 3

7

启动一个新线程,该线程Process.waitFor()在该调用返回时调用并设置一个标志。然后,您可以随时检查该标志,以查看该过程是否已完成。

public class ProcMon implements Runnable {

  private final Process _proc;
  private volatile boolean _complete;

  public boolean isComplete() { return _complete; }

  public void run() {
    _proc.waitFor();
    _complete = true;
  }

  public static ProcMon create(Process proc) {
    ProcMon procMon = new ProcMon(proc);
    Thread t = new Thread(procMon);
    t.start();
    return procMon;
  }
}

(省略了一些样板)。

于 2012-07-16T18:50:35.377 回答
5

我不确定我是否理解这个问题,但一种方法是调用process.exitValue();. 如果进程尚未终止,则会引发异常:

/**
 * Returns the exit value for the subprocess.
 *
 * @return  the exit value of the subprocess represented by this 
 *          <code>Process</code> object. by convention, the value 
 *          <code>0</code> indicates normal termination.
 * @exception  IllegalThreadStateException  if the subprocess represented 
 *             by this <code>Process</code> object has not yet terminated.
 */
abstract public int exitValue();

如果您不介意 hack,如果您在使用UNIXProcess该类的 ~Unix 系统上工作,则可以执行以下操作。但是,这确实使用了反射:

ProcessBuilder pb = new ProcessBuilder("/bin/sleep", "5");
Process process = pb.start();
// open accessability of the UNIXProcess.hasExited field using reflection
Field field = process.getClass().getDeclaredField("hasExited");
field.setAccessible(true);
// now we can get the field using reflection
while (!(Boolean) field.get(process)) {
    ...
}
于 2012-07-16T18:40:25.587 回答
2

根据问题的特定代码片段,我可能有用的是添加自 1.8 以来Process该类有一个isAlive()方法可用

文档链接:https ://docs.oracle.com/javase/8/docs/api/java/lang/Process.html

祝所有阅读本文的人好运!

于 2017-07-12T17:49:06.107 回答