Java process.getInputStream()无需读取,死锁子

我遇到了一些进程包装的问题,它只发生在Windows XP中。 这段代码在Windows 7中完美运行。我真的很难过为什么XP中的流是空的。 我也尝试使用Process.Exec()的String []版本,但它没有任何区别。

我正在使用以下类从进程’STDOUT和STDERR(每个流的一个实例)中读取:

import java.util.*; import java.io.*; public class ThreadedStreamReader extends Thread{ InputStream in; Queue messageQueue; public ThreadedStreamReader(InputStream s, Queue q) { in = s; messageQueue = q; } public void run() { try { BufferedReader r = new BufferedReader(new InputStreamReader(in)); String line = null; while((line = r.readLine()) != null) { synchronized(messageQueue) { messageQueue.add(line); } } }catch(Exception e) { System.err.println("Bad things happened while reading from a stream"); } } } 

我在这里使用它:

 Process p = Runtime.getRuntime().exec("test.exe"); Queue q = new LinkedList(); ThreadedStreamReader stdout = new ThreadedStreamReader(p.getInputStream(), q); ThreadedStreamReader stderr = new ThreadedStreamReader(p.getErrorStream(), q); stdout.start(); stderr.start(); while(true) { while(q.size() > 0) { System.out.println(q.remove()); } } 

有人有主意吗? 谢谢!

编辑:添加同步

编辑:就像更新一样,父流读取器在读取操作时被阻止。 如果我使用任务管理器终止子进程,它们会从流的关闭中读取null。

您需要使用线程安全的数据结构; 我不认为LinkedList是线程安全的。

令我LinkedList一个错误是LinkedList没有同步 ,但是你试图在2个线程中写入它。

要记住的另一件事是Process.getInputStream()返回进程的stdout流,因此您应该将当前名为stdin的变量重命名为stdout以防止混淆。

在Vista之前的Windows操作系统中存在已知错误,其中加载DLL可能导致IO挂起。

例如,请参阅http://weblogs.java.net/blog/kohsuke/archive/2009/09/28/reading-stdin-may-cause-your-jvm-hang和https://connect.microsoft.com/VisualStudio/反馈/信息/ 94701 /的LoadLibrary-死锁上带有一个读管

我不确定这是不是你正在运行的,但它可能是相关的。

另外,我模糊地回忆起从非控制台窗口应用程序获取有效stdin和stdout的一些问题。 如果你对’test.jar’的调用是使用’javaw’而不是’java’,那么这也可能是你问题的原因。

由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。