问题描述
我的Java应用程序正在使用Runtime.exec(String [],String [],File)启动外部程序。总的来说,这很好。但是,我注意到Linux与Windows之间的重要区别。建议以下代码段:
Process pr = Runtime.getRuntime(cmdArray,env,workDir);
startThreadProcessingStdout(pr.getInputStream());
startThreadProcessingStderr(pr.getErrorStream());
int status = pr.waitFor();
在Windows上,当waitFor()返回时,我的线程已完成。 (至少从某种意义上说,他们已经看到了所有必需的输入。)
但是,在Linux上,进程已消失,但是线程仍在忙于读取输入。我可以通过如下更改代码段来解决此问题:
Process pr = Runtime.getRuntime(cmdArray,workDir);
AtomicBoolean outRunning = startThreadProcessingStdout(pr.getInputStream());
AtomicBoolean errRunning = startThreadProcessingStderr(pr.getErrorStream());
int status = pr.waitFor();
while (outRunning || errRunning) {
Thread.sleep(100);
}
但是,这似乎笨拙且缓慢。我的问题有更好的解决方案吗?
解决方法
听起来您正在运行的程序启动了自己的后台子进程,并且该子进程继承了stdout和stderr文件描述符。
Process.waitFor
等到父进程退出。如果这样做,它将使子进程保持运行状态。由于子进程继承了stdout和stderr,因此用于与Java程序通信的管道将保持打开状态,直到子进程退出(或通过其他方式将其关闭)。