在while循环的开头的条件语句没有被检查

4

我注意到这个问题(如果它是一个问题),并决定建立一个测试环境。有人知道这是一个实际的问题还是只有我遇到了吗?

import java.util.Random;

public class Start {

    public static boolean value;

    public static void main(String[] args){
        Thread thread = new Thread(){
            @Override
            public void run(){
                random();
            }
        };
        thread.start();
        while(true){
            if(value) System.out.println("Done");
        }
    }

    public static void random(){
        while(true){
            value = new Random().nextInt(5) == 0;
        }
    }

}

我希望这段代码能够一直输出“Done”,但实际上它只在一开始输出了一堆,之后就没有再输出了。当我将代码修改为以下内容时:

while(true){
System.out.print(""); //Modification
    if(value) System.out.println("Done");
}

它开始不断发送“完成”消息。有人知道是怎么回事吗? 注意:我已经在Eclipse环境和使用jdk 1.8.0 v.25和jre 1.8.0 v.51编译的jar中进行了测试。


2
你正在进行竞赛。将值声明为volatile,但这仍然不能使代码正确。 - Falmarri
2
你可以看一下这个:https://dev59.com/A4zda4cB1Zd3GeqPjTRb#30965392 - Jean-François Savard
1
将其声明为volatile后问题得到解决,现在正常运行。谢谢。 - Noah
2
@Noah 我仍然建议阅读我提供的链接,以了解为什么 System.out.println 调用会改变行为... - Jean-François Savard
1
我做了,所以我理解了。感谢您的帮助! - Noah
1个回答

3
我猜测你遇到了一个编译器优化,称为hoisting - 它认识到你在没有让其他线程“看到”这些更改的情况下覆盖了value,因此它会在某个时候进行优化并停止打印。
一旦你将value声明为volatile,这种行为就会改变成为可能是“想要”的行为 - 然后对它的更新将变得可见于其他线程,然后打印将永远继续。

2
打印行为会改变,因为底层流是同步的,从而强制线程进行同步。 - Jean-François Savard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接