即使在mutithreaded popgram中满足条件之后,while循环也不会以java结尾

时间:2017-06-20 14:57:16

标签: java multithreading

我有一个多线程程序,它在某种特定条件下显示出奇怪的行为。由于专有问题,我不能在这里发布完整的代码,但我在这里提出示例错误。

我有一个类,它有一个布尔变量,并且正在扩展Java Thread类

public class 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;
}

}

此Thread在其他类中使用如下:

public class 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()调用尝试将boolean复制到新的内存地址,并且无情的轮询不允许它。

请分享您在此问题上的经验和知识。

1 个答案:

答案 0 :(得分:2)

在多线程环境中,当一个线程更改一个值应该对其他线程可见时,您需要可见性。对于您的情况,您可以使用volatile boolean flag或使用AtomicBoolean变量类型,以便其他线程可见当一个线程更改值时。

volatile boolean done = false;