在java中确定使用Runtime环境创建的进程是否已完成执行?

时间:2011-07-29 13:24:39

标签: java runtime.exec

Runtime.getRuntime.exex("abc.exe -parameters");

使用.waitFor()无助于确定流程的完成情况。

4 个答案:

答案 0 :(得分:17)

看起来JDK8引入了Process.isAlive()。感到惊讶花了这么久......

与此同时,最佳选择似乎是轮询Process.exitValue(),包含在try-catch中:

// somewhere previous...
String[] cmd = { "abc.exe", "-p1", "-p2" };
Process process = Runtime.getRuntime.exec(cmd);

// call this method repeatedly until it returns true
private boolean processIsTerminated () {
    try {
        process.exitValue();
    } catch (IllegalThreadStateException itse) {
        return false;
    }
    return true;
}

或者,类似的方法可以在进程终止时返回退出值,如果没有则返回其他指定值。

答案 1 :(得分:9)

Process.waitFor()javadoc工作。如果它不起作用,那么:

  • JVM或操作系统中存在一个错误(极不可能出现类似的错误)或

  • 关于流程和/或您的Java代码,这意味着流程不会退出。


在当前版本的Java中,您还可以使用Process.isAlivejavadoc)来测试进程状态,直到完成为止。对于Java 7及更早版本,有一个hacky解决方案需要轮询进程返回代码并捕获异常,但这是低效的。您应该尽快升级到Java 8或更高版本!


  

任务完成后,无限期等待。 (我不知道为什么)。

如果发生这种情况,那么waitFor()isAlive()都无济于事。

从Java启动的进程不会/不能退出的最可能原因是:

  • 阻止进程等待Java应用程序给它一些输入(通过其stdin),

  • 阻止进程等待Java应用程序读取其输出(即其stdout或stderr),

  • 等待某些外部事件被阻止;例如如果它试图说话没有响应的远程服务器,

  • 某些东西发送了某种停止信号,或者

  • 只是花了 looong 时间来运行。

这两个原因/原因中的前两个可以通过(分别)关闭连接到其标准输入的Java输出流,以及读取(并可能丢弃)连接到其标准输出和标准错误的Java输入流来解决。其他原因是棘手的,你唯一的选择就是“等待它”或者试图杀掉这个过程。


底线 - 您需要找出您的流程未完成的原因。被阻止的Process.waitFor()呼叫是一种症状,而不是疾病。

答案 2 :(得分:1)

我有类似的问题,这里写的方法都不适合我。这是我的代码:

public void startCCleaner() {
    System.out.println("Starting ccleaner...");
    try {
        Process process = new ProcessBuilder("C:\\Program Files\\CCleaner\\CCleaner64.exe").start();
        if(process.waitFor() == 0 ){
            System.out.println("Process terminated ");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

答案 3 :(得分:-1)

如果你不想使用waitFor(),显然你没有,你可以直接测试退出值。

import java.util.*;
import java.io.*;
public class ProcExitTest
{
    public static void main(String args[])
    {
        try
        {            
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec("<....>");
            int exitVal = proc.exitValue();
            System.out.println("Process exitValue: " + exitVal);
        } 
          catch (InterruptedException ie)
          {
            ie.printStackTrace();
          }
    }
}

退出代码0表示正常终止。