hqt*_*hqt 11 java multithreading volatile
在java中,据我所知,volatile变量使一个线程直接读/写到主CPU(而不是每个线程的缓存中),因此将其更改显示给其他线程.
我不知道的是:所以,为什么这个(volatile)工作可以阻止编译器/ CPU重新排序代码语句.
谢谢 :)
das*_*ght 21
这是一个非常好的例子,说明禁止重新排序旨在解决的问题(取自此处):
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.
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,v是volatile,但x不是.如果作者和读者同时执行并且读者看到v设置true,x则保证是42.在Java-5之前,编译器可以自由地重新排序写入x和v,因此x在看到set 之后你可以看到零.这令人困惑,并导致微妙的错误.Java-5内存模型通过使易失性写入几乎等同于同步来解决此问题.vtrue
这就是语言的定义方式.非正式地,volatile在Java中标记变量特别告诉编译器它不应该重新排序它周围的语句或优化它的值,因为该值可能在另一个线程中同时修改.然后,JVM的特定实现负责volatile遵守此修饰符并采取适当的预防措施,以避免错误地优化程序.
如果您想了解有关确保volatile正常工作的语言级保证的更多具体细节,您可能需要查看Java语言规范对Java内存模型的描述,该描述定义了管理线程行为的抽象规则.它还描述了如何volatile与这些规则进行交互.
希望这可以帮助!