Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
而在多线程popgram中,即使满足条件,循环也不会在java中结束_Java_Multithreading - Fatal编程技术网

而在多线程popgram中,即使满足条件,循环也不会在java中结束

而在多线程popgram中,即使满足条件,循环也不会在java中结束,java,multithreading,Java,Multithreading,我有一个多线程程序,它在某种情况下表现出奇怪的行为。由于专有问题,我不能在这里发布完整的代码,但我将示例错误放在这里 我有一个类,它有一个布尔变量,正在扩展Java线程类 public class SystemStreamCapture extends Thread { InputStream is; boolean done = false; List<String> buffer; private final static Logger Log

我有一个多线程程序,它在某种情况下表现出奇怪的行为。由于专有问题,我不能在这里发布完整的代码,但我将示例错误放在这里

我有一个类,它有一个布尔变量,正在扩展Java线程类

public class SystemStreamCapture extends 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;
    }
}
公共类SystemStreamCapture扩展了线程{
输入流为;
布尔完成=假;
列表缓冲区;
私有最终静态记录器Log=Logger.getLogger(SystemStreamCapture.class);
公共系统流捕获(InputStream为){
this.is=is;
}
公开募捐{
试一试{
InputStreamReader isr=新的InputStreamReader(is);
BufferedReader br=新的BufferedReader(isr);
字符串行=null;
而((line=br.readLine())!=null){
this.buffer.add(行);
}
br.close();
isr.close()
}捕获(ioe异常ioe){
日志错误(ioe);
}最后{
this.done=true;
}
}
公共列表getData(){
返回此.buffer;
}
公共布尔isDone(){
归还这个。完成;
}
}
此线程在其他类中使用,如下所示:

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();
    }
公共类文件读取器{
私有最终静态记录器Log=Logger.getLogger(FileReader.class);
公共列表读取行(FileLineRequestModel请求)引发IOException{
String[]script={“/bin/sh”,“-c”,request.getCommand()};
调试(“执行行提取命令:+request.getCommand());
进程p=Runtime.getRuntime().exec(脚本);
SystemStreamCapture errStream=新的SystemStreamCapture(p.getErrorStream());
SystemStreamCapture outStream=新的SystemStreamCapture(p.getInputStream());
errStream.start();
outStream.start();
而(!outStream.isDone()){
//继续循环
//调试(“读取…”);
}
返回outStream.getData();
}
奇怪的部分是后一个类中的while循环。尽管“done”变量变为“true”,但循环永远不会结束。我还尝试了语法“
(outStream.isDone()==false)
”,只是为了看看它是否有任何区别(我知道不会)。 然而,只要我在while中打开“
Log.debug”(“reading…”)
”,它就会正常工作

我不知道发生了什么,可能是outStream.isDone()调用试图将布尔值复制到新的内存地址,而无情的轮询不允许这样做


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

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

volatile boolean done = false;

不看那堆代码,有一条规则:在
finally
语句中关闭流,或者使用try-with-resources。您是否查看文档以了解如何读取
getErrorStream
?检查它是否仍然可用()您未使用的。有关详细信息:使
完成
易失性
。尝试将
完成
标记为
易失性
。并且为了使其线程安全而不必同步,可能会更改为
原子布尔
。请编辑您的答案,以显示哪个变量应该是
易失性
。谢谢有帮助。@vaibhav singh,如果你认为它对你有用,那么就投票吧,这样对其他人也会有帮助。