流程挂在流程生成器上

时间:2017-02-24 10:29:19

标签: java multithreading jvm deadlock

我正在研究java进程构建器来执行windows外部进程(即exe文件)。我必须使用输入流,错误流将进程信息和错误写入一些文本文件中。

它有时会工作,有时会意外地挂起。

当我调用三个外部进程来逐个执行时。两个流程正在工作,它只在第三个流程上挂起。

我可以看到进程退出值为0,有时会给出一些其他随机值。

我已阅读以下博客并应用相同的逻辑来执行该过程但不适用于我的方案。

请有人帮我诊断这些问题......

//开始启动外部流程  //此代码将从中依次选择三个参数来执行该过程  //它会逐个通过for循环传递进程命令

 Process p =new ProcessBuilder(s)
               .directory(new File(je.getExecution().getWorkingDirectory()))
               .redirectErrorStream(true)
               .redirectOutput(file)
               .start();

p.getOutputStream().close();
int processStatus= p.waitFor();

//如果进程以0正常终止退出

提前致谢..,

1 个答案:

答案 0 :(得分:2)

你正在做的所有事情都容易出错,并且不值得尝试找出所有的错误,因为你正在不必要地努力生活。

请注意,您正在调用redirectErrorStream(true),但仍在尝试从错误流中读取,这没有任何意义。在这种情况下,错误流将始终为空。也就是说,如果您已经了解重定向,则不清楚,为什么不直接使用它们,而不是创建线程,手动将数据复制到StringWriter等等。

显然,您希望使用工作目录je.getExecution().getWorkingDirectory(),启动命令s并将程序的输出和错误指向file。这可以像

一样简单实现
new ProcessBuilder(s)
    .directory(je.getExecution().getWorkingDirectory())
    .redirectErrorStream(true).redirectOutput(file)
    .start()
    .waitFor();

唯一剩下的错误来源是启动的进程可以等待来自您身边的输入。由于您显然不想提供输入,您可以使用

Process proc = new ProcessBuilder(s)
    .directory(je.getExecution().getWorkingDirectory())
    .redirectErrorStream(true).redirectOutput(file)
    .start();
proc.getOutputStream().close();
proc.waitFor();

表示您不会写任何数据。这不会停止进程,但是当它尝试从标准输入读取内容时,它会立即获得文件结束而不会阻塞。

可以用

来证明
Process proc = new ProcessBuilder("cmd", "/c", "pause")
    .redirectErrorStream(true).redirectOutput(file)
    .start();
proc.getOutputStream().close();
proc.waitFor();