Runtime.exec().waitFor()实际上并没有等待

Rhy*_*hys 12 java multithreading runtime.exec

我有一些代码使用Runtime.exec()运行外部.jar(构建为IzPack安装程序).

如果我从命令行运行这个external.jar,如下所示:

java -jar external.jar
Run Code Online (Sandbox Code Playgroud)

然后,在应用程序完成之前,命令提示符不会返回控制.但是,如果我从某个java类中运行external.jar,则使用:

Process p = Runtime.getRuntime().exec("java -jar external.jar");
int exitCode = p.waitFor();
System.out.println("Process p returned: " + exitCode);
Run Code Online (Sandbox Code Playgroud)

然后p几乎立即返回成功代码0,尽管external.jar尚未完成执行(我也通过ProcessBuilder外部文件执行路径尝试了这一点).

为什么它等待从命令行返回,但是从另一个java程序执行时却没有?

我还设置了3个罐子,A,B和C,其中A调用B调用C(使用Runtime.exec()),其中C Thread.sleeps为10秒,作为一个简单的测试,并且如预期的那样,A直到10秒后才返回它运行.

我认为这可能是external.jar的某种线程问题,其中执行是从一件事移交给另一件事,但鉴于它直接从命令行工作,我希望看到相同的行为(可能是天真的)从另一个java程序中调用时.

我已经在Windows和Ubuntu上用Java 6测试了这个.

谢谢!

ant*_*per 6

另一种可能的方法是捕获进程的输出并等待它完成.

例如:

Process tr = Runtime.getRuntime().exec( new String[]{"wkhtmltopdf",mainPage,mainPagePDF});
BufferedReader stdOut=new BufferedReader(new InputStreamReader(tr.getInputStream()));
String s;
while((s=stdOut.readLine())!=null){
       //nothing or print
}
Run Code Online (Sandbox Code Playgroud)

通常输出流是tr.getInputStream()但是根据您正在执行的程序输出流migh是:

  • tr.getInputStream()
  • tr.getErrorStream()
  • tr.getOutputStream()

通过执行此循环,您可以强制程序等待该过程完成.

  • 这实际上对我有用.waitFor()立即返回(例如,因为主线程已经结束)但只要进程尚未完全终止,流将保持可访问状态. (2认同)

Mat*_*ake 0

您是否生成一个新线程来处理进程的生成?如果是这样,原始程序将继续独立于生成的进程运行,因此 waitFor() 将仅适用于新进程,而不适用于父进程。