是否保证在另一个线程中看到一个线程中非易失性成员变量的赋值?

考虑下面的Java示例。 请注意,两个类成员变量都没有声明为volatile 。 如果我正在理解内存模型并且“之前发生”规则正确,Java实现可以优化run()方法,以便它永远运行,即使另一个线程调用stopNow()方法。 这可能发生,因为run()方法中没有任何内容强制线程多次读取stop的值。 那是对的吗? 如果没有,为什么不呢?

 class Example implements Runnable { boolean stop = false; int value = 0; public void stopNow() { stop = true; } public int getValue() { return value; } @Override public void run() { // Loop until stop is set to true. while (!stop) { ++value; } return; } } 

可以被另一个线程修改,但这不是gurranteed。 这也不是线程安全的。 要使变量gurranteed从另一个线程中看到,您需要执行以下任何操作

只有在以下条件下,才能保证一个线程对字段的更改对其他线程可见:

  • 写入线程释放同步锁,读取线程随后获取相同的同步锁。
  • 如果一个字段被声明为volatile,那么写入它的任何值都会被刷新,并且在写入器之前由编写器线程使其可见
    线程执行任何进一步的内存操作(即,用于此目的
    在手边它立即被冲洗)。 读者线程必须重新加载
    每次访问时的volatile字段的值。
  • 线程第一次访问对象的字段时,它会看到字段的初始值或自某个其他线程写入的值。
  • 当一个线程终止时,所有写入的变量都被刷新到主存储器。 例如,如果一个线程使用Thread.join在另一个线程的终止上同步,则保证看到
    该线程产生的影响(见§4.3.2)。

有用的SO线程

那是对的。 这是您可能想要使用volatile的原因之一。