java - Volatile:为什么要阻止编译器重新排序代码

标签 java multithreading volatile

在 java 中,据我所知,volatile 变量使线程直接读取/写入主 CPU(不在每个线程的缓存中),因此使其更改对其他线程可见。

我不知道的是:那么,为什么这项工作(volatile 的)可以防止编译器/CPU 对代码语句重新排序。

谢谢:)

最佳答案

这是一个很好的例子,说明了禁止重新排序旨在解决的问题(摘自 here):

class VolatileExample {
    int x = 0;
    volatile boolean v = false;
    public void writer() {
        x = 42;
        v = true;
    }
    public void reader() {
        if (v == true) {
            //uses x - guaranteed to see 42.
        }
    }
}

在此示例中,v 是可变的,但 x 不是。如果 writer 和 reader 并发执行并且 reader 看到 v 设置为 true,则 x 保证为 42 .在 Java-5 之前,编译器可以自由地重新排序对 xv 的写入,因此您可以看到 x 为零 after 你看到 v 设置为 true。这令人困惑,并导致微妙的错误。 Java-5 内存模型通过使 volatile 写入几乎等同于同步来解决这个问题。

关于java - Volatile:为什么要阻止编译器重新排序代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9187527/

相关文章:

java - 如何使 Logo 在 ActionBar 中居中?

java - 新的 Java applet 插件没有被使用?

c++ - 尝试在类构造函数中初始化 std::thread 时,函数中出现编译器错误 C2064

java - 无法使用 Selenium 网格中的 maxSession 将浏览器 session 限制为 1 (Java)

java - 如何在方法和线程之间共享字符串?

java - 如何将参数化匿名类转换为 lambda?

java - JOptionPane.showInputDialog 的用户输入验证

c++ - _ReadWriteBarrier 如何向上传播调用树?

rust - 有没有办法防止发出的 LLVM IR 删除未使用的函数?

c++ - C/С++。为什么 volatile 上的简单整数加法可以转换为 gcc 和 clang 上的不同 asm 指令?