Jim*_*Jim 7 java multithreading outputstream executorservice processbuilder
我用a ProcessBuilder来运行进程.我通过提交在线程池(Executors.newCachedThreadPool())中处理它们的相应runnable来处理输入/输出流.
我得到了结果但是偶尔我什么也得不到.
例如,如果我这样做:cmd \C dir对于流程构建器,我得到了dir返回的结果,但有时我没有得到任何东西(尽管结果似乎从处理它的runnable中恢复process.getInputStream).
我该怎么调试呢?它间歇地出现了.使用相同的代码,我没有遇到任何问题new Thread(runnable).start().它在我切换到线程池后开始发生.
更新:
我想我找到了一些东西:
我在以下方面做了以下事情Runnable:
try {
while ( (line = br.readLine()) != null) {
pw.println(line);
sb.append(line);
}
System.out.println("Finished reading "+sb.length());
} catch (IOException e) {
e.printStackTrace();
}
finally{
pw.flush();
try{
isr.close();
}catch(Exception e){}
}
Run Code Online (Sandbox Code Playgroud)
在不起作用的情况下,它打印Finished reading 521.但我试图通过pw而不是得到结果sb.
pw是PrintWriter pw = PrintWriter(outputStream);`我传递给runnable
更新2:
似乎:在处理输入流的runnable完成之前status = process.waitFor();返回.怎么会发生这种情况?
我在javadoc中读到:.那么这是否意味着我可以在消耗I/O流之前返回?
the calling thread will be blocked until the subprocess exits
更新3:
在Ruby中似乎是同样的问题
即在进程结束和消耗输出之间存在一些竞争条件
是的。进程之间的stdio是有缓冲的(通常是4KB缓冲区)。进程A写入缓冲区并存在。进程B有两个线程;一个等待 A 的末尾,另一个读取 A 的输出。无法确定哪个线程先执行。
因此,有可能(甚至在有大量输出时)process.waitFor();在读取所有缓冲输出之前返回。
请注意,刷新在这里没有帮助,因为它只是确保 A 已写入所有内容。没有办法以类似的方式“强制”B读取数据。
因此,您应该记住退出状态,并仅当您从输入流读取 EOF 时才将进程视为“完全终止”。
编辑一种解决方案是将waitFor()gobbler 移入流 gobbler 并将 gobbler 转换为 a Callable,然后您可以将其提交给执行器并使用FutureAPI(示例)来获取结果。
| 归档时间: |
|
| 查看次数: |
498 次 |
| 最近记录: |