我有以下代码;
String[] cmd = { "bash", "-c", "~/path/to/script.sh" };
Process p = Runtime.getRuntime().exec(cmd);
PipeThread a = new PipeThread(p.getInputStream(), System.out);
PipeThread b = new PipeThread(p.getErrorStream(), System.err);
p.waitFor();
a.die();
b.die();
PipeThread
类非常简单,所以我将其全部包含在内;
public class PipeThread implements Runnable {
private BufferedInputStream in;
private BufferedOutputStream out;
public Thread thread;
private boolean die = false;
public PipeThread(InputStream i, OutputStream o) {
in = new BufferedInputStream(i);
out = new BufferedOutputStream(o);
thread = new Thread(this);
thread.start();
}
public void die() { die = true; }
public void run() {
try {
byte[] b = new byte[1024];
while(!die) {
int x = in.read(b, 0, 1024);
if(x > 0) out.write(b, 0, x);
else die();
out.flush();
}
}
catch(Exception e) { e.printStackTrace(); }
try {
in.close();
out.close();
}
catch(Exception e) { }
}
}
我的问题是这个;即使在子进程终止后,p.waitFor()
也会无休止地阻塞。如果我不创建一对PipeThread
个实例,那么p.waitFor()
就能完美运行。 io流的管道是什么导致p.waitFor()
继续阻塞?
我很困惑,因为我认为IO流是被动的,无法保持进程存活,或者让Java认为进程仍然存在。
答案 0 :(得分:0)
在您的PipeThread
代码中,您将永远循环直到!die - 但是在PipeThread.die()
之后调用p.waitFor()
- 究竟是什么阻止了PipeThread
个帖子?
答案 1 :(得分:0)
因此,经过多次头疼,我意识到发生了什么。 p.waitFor()
实际上不是无限期地阻止,而是我检查它的方法失败了; System.out.println()
之后的p.waitFor()
语句。
PipeThread
是我在之前的项目中所处的类,我经常使用它在一个单独的线程中将一个流传输到另一个流。
这必须是我第一次将其与System.out
一起使用。 PipeThread
会在阅读EOF
时关闭传递的所有流。在这种情况下,两个流都包含我的标准输出,因此使用System.out.println
进行调试变得不可能...... :(
奇怪的是,IOException
没有抛出System.out.println()
,我会调查。