我有一個多線程程序,它在一定條件下顯示奇怪的行爲。由於專有的問題,我不能在這裏發佈完整的代碼,但我在這裏提供了示例bug。即使在mutithreaded popgram條件滿足的情況下while循環不會以java結尾
我已經具有一個布爾變量,並延伸Java線程類中的一個類
公共類SystemStreamCapture擴展Thread {
InputStream is;
boolean done = false;
List<String> buffer;
private final static Logger Log = Logger.getLogger(SystemStreamCapture.class);
public SystemStreamCapture(InputStream is) {
this.is = is;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
this.buffer.add(line);
}
br.close();
isr.close()
} catch (IOException ioe) {
Log.error(ioe);
} finally {
this.done = true;
}
}
public List<String> getData() {
return this.buffer;
}
public boolean isDone() {
return this.done;
}
}
此線程其它類內使用如下:
公共級FileReader {
private final static Logger Log = Logger.getLogger(FileReader.class);
public List<String> readLines(FileLineRequestModel request) throws IOException {
String[] script = { "/bin/sh", "-c", request.getCommand() };
Log.debug("executing line fetch command : " + request.getCommand());
Process p = Runtime.getRuntime().exec(script);
SystemStreamCapture errStream = new SystemStreamCapture(p.getErrorStream());
SystemStreamCapture outStream = new SystemStreamCapture(p.getInputStream());
errStream.start();
outStream.start();
while (!outStream.isDone()) {
// keep looping
//Log.debug("reading...");
}
return outStream.getData();
}
奇怪的部分是後面的類中的while循環。即使「完成」變量變爲「真」,循環也不會結束。我也試過語法'(outStream.isDone() == false)
',只是爲了看看它是否有所作爲(我知道不會)。 但是,只要我在內部轉入'Log.debug("reading...")
',它就會按預期工作。
我不知道發生了什麼,也許outStream.isDone()調用嘗試將布爾值複製到新的內存地址,無情的輪詢不允許它。
請分享你在這個問題上的經驗和知識。
不看那堆代碼,一條規則:在'finally'語句中關閉流,或者使用try-with-resources。 – Mena
您是否檢查過文檔以查看您應該如何閱讀'getErrorStream'?有一個檢查,如果它仍然是'可用'()'你沒有使用。欲瞭解更多信息:https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html – alfasin
使'完成''易揮發'。 –