This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
                                
                                    (1个答案)
                                
                        
                4年前关闭。
            
        

在图形类中,我拥有它,因此当您按“ m”时,它使布尔值M为true,然后得到这段代码。

graphic.m = false;
while(graphic.m == false){
}
graphic.m = false;


它不起作用,它不会继续执行前面的代码。

但是如果我这样做

graphic.m = false;
while(graphic.m == false){
System.out.println("m");
}
graphic.m = false;


它非常有效,有人可以解释为什么以及如何克服吗?

最佳答案

为使此功能正常工作,其他线程必须将graphic.m设置为true。因此,我假设情况正在发生。

我的猜测是graphic.m不是可变字段。这意味着一个线程向它写入(从另一个线程将其设置为true)与另一个线程从其读取(您拥有的代码)之间没有正式的事前关系。 JVM可以自由地在线程内缓存值(或让CPU内核对其进行缓存等),并且似乎正在这样做。

但是,System.out.println是一种同步方法。即使根据JLS,这对graphic.m并没有任何形式上的影响,但很有可能,释放/获取同步锁的行为会刷新内核中的内存,以便您的线程恰巧看到graphic.m的最新消息。值。要强调的是:这不是Java规范所必需的,并且您不应该依赖这种行为-如果这样做,则可能会在将来的版本中被难以捕获的bug所咬。 JVM或一些稍微不同的硬件等。

解决方案是将graphic.m设置为volatile字段(或通过同步方法获取/设置它,或使用AtomicBoolean)。

09-30 14:06