Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Java Volatile:为什么要阻止编译器重新排序代码_Java_Multithreading_Volatile - Fatal编程技术网

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

Java Volatile:为什么要阻止编译器重新排序代码,java,multithreading,volatile,Java,Multithreading,Volatile,据我所知,在java中,volatile变量使线程直接读/写主CPU(不在每个线程的缓存中),因此使其更改对其他线程可见 我不知道的是:那么,为什么这项工作(volatile)可以阻止编译器/CPU对代码语句进行重新排序呢 谢谢:)这就是语言的定义。非正式地说,在Java中标记一个变量volatile,特别告诉编译器不应该对其周围的语句重新排序或对其值进行优化,因为该值可能会在另一个线程中同时修改。JVM的特定实现负责遵守此volatile修饰符,并采取适当的预防措施以避免错误地优化程序 如果您

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

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


谢谢:)

这就是语言的定义。非正式地说,在Java中标记一个变量
volatile
,特别告诉编译器不应该对其周围的语句重新排序或对其值进行优化,因为该值可能会在另一个线程中同时修改。JVM的特定实现负责遵守此
volatile
修饰符,并采取适当的预防措施以避免错误地优化程序

如果您想了解有关哪些语言级别的保证可以确保
volatile
正常工作的更具体的细节,您可能需要查看,它定义了控制线程行为的抽象规则。它还描述了
volatile
如何与这些规则交互


希望这有帮助

这是一个很好的例子,说明了禁止再订购旨在解决的问题(摘自):


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

我不知道如何保证读卡器(见第42页的x)。确保x=42可以发生在v=true之前,但是reader()仍然可以看到缓存值0,否?@Shawn,直到Java-5这是正确的,但是Java-5内存模型确保所有写入都在易失性写入之前完成。有关详细信息,请参阅链接。我只是根据这个答案运行了我的代码,并注意到以下事实。如果v声明为true,编译器可以删除行
v=true
,并且x的值在
reader()中保持为0。请参阅,但如果在writer()中设置v之后设置了x,则reader()会将x设置为42或0注意,关于volatile使读取避免缓存的这件事纯粹是一个理论构造,实际上与真正的硬件上的
volatile
实际功能没有太大关系。我们只是想象一个实现可能会做各种事情,
volatile
保证优化不会产生我们需要在特定情况下禁止的特定行为。
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.
        }
    }
}