Java易失性和副作用

Oracle关于primefaces访问的文档( http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html )说明了这一点:

“一个volatile变量建立一个发生在之前的关系…….这意味着……当一个线程读取一个volatile变量时,它不仅会看到volatile的最新变化,还会看到导致的代码的副作用改变。”

我无法绕过那条头。 我理解volatile变量是如何工作的(在> = Java 5中),但是我想知道java如何决定哪些副作用“导致”变化为volatile变量。

所以我想我的问题是:这种保证有哪些副作用?

编辑:

所以我已经知道如果线程A修改了一个volatile变量,然后线程B读取它,那么在写入volatile变量之前发生的所有线程A的写入都与线程B“相关”(即缓存的值)由线程A进行的前述写入的变量在线程B)中无效。 如我错了请纠正我。

大多数多处理器缓存具有一致性机制,因此惩罚并不像刷新所有缓存那样糟糕。

在执行此操作之前,写入volatile的线程中的任何写入都将被读取volatile的线程看到。

以Double Checked Locking为例。 创建对象时,很多事情都发生在幕后:

MyClass c=new MyClass(); 

分配内存,调用构造函数,并将内存位置分配给变量c。 允许JVM重新排序这些操作。 如果分配了内存,分配了值,并且线程在调用构造函数之前中断并使用该值,则会导致问题。

 volatile MyClass c=new MyClass(); 

根据1.5规则,保证分配是这些事件中的最后一个。 “副作用”是分配和构造函数调用。