使用ProcessBuilder执行进程会导致等待waitFor

问题描述:

我在使用Java运行外部应用程序时遇到问题。我知道与输入和输出流的问题,而我试图阅读如下:使用ProcessBuilder执行进程会导致等待waitFor

ProcessBuilder pb = new ProcessBuilder(args); 
    args[args.length - 1] += "<NUL"; 

    pb.redirectErrorStream(true); 
    Process p = pb.start(); 

    InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
    BufferedReader input = new BufferedReader(isr); 
    while (input.readLine() != null) { 
    }  

    p.waitFor(); 
    input.close(); 
    isr.close(); 

我执行的命令是XDG-打开一个URL,所以它不该”等待输入。

这可以在我的机器上十次运行九次,但有时它只是挂在pb.start();并且该命令不被执行。

java线程正在等待进程返回。这里的堆栈跟踪:

Name: LinkHandlerExec 
State: WAITING on [email protected] 
Total blocked: 0 Total waited: 1 

Stack trace: 
java.lang.Object.wait(Native Method) 
java.lang.Object.wait(Object.java:502) 
java.lang.UNIXProcess$Gate.waitForExit(UNIXProcess.java:80) 
java.lang.UNIXProcess.<init>(UNIXProcess.java:161) 
java.lang.ProcessImpl.start(ProcessImpl.java:81) 
java.lang.ProcessBuilder.start(ProcessBuilder.java:468) 

这里就是strace的告诉我:

$ sudo strace -p 13255 
Process 13255 attached - interrupt to quit 
futex(0x7fbb673e49d0, FUTEX_WAIT, 13262, NULL 
+0

这与此相关吗?http://*.com/questions/1043611/failure-to-start-program-from-java-using-processbuilder?rq=1 – Baz 2012-08-01 09:25:15

+0

while(input.readLine()!= null ){} //空,而这只是在你的原始代码 – 2012-08-01 09:25:26

+0

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=2 – 2012-08-01 09:40:06

我们在CentOS 6.3 JDK 1.6.0_33-B03观察到这样的问题。调查显示,这是在此Java进程中发生OutOfMemoryError之后发生的。

寻找类java.lang.UNIXProcess的代码我想,当在UNIXProcess构造函数中运行的单独线程中引入非IO异常(例如错误)时,可能会发生此类问题, 130.该代码将更好地被组织为

try { 
    ..... 
} finally { 
    gate.exit(); 
} 

,而是它的组织结构

try { 
    ... 
} catch (IOException e) { 
    gate.setException(e); /*remember to rethrow later*/ 
    gate.exit(); 
    return; 
} 
... 
gate.exit(); 

,所以非IO异常可能会导致gate.exit()不要被所谓什么导致主要线程在方法gate.wa中永远挂断itForExit()(第145行)。