Java易失性和副作用

时间:2012-02-07 00:10:04

标签: java concurrency atomic volatile side-effects

Oracle关于原子访问的文档(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)中无效。如果我错了,请纠正我。

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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

MyClass c=new MyClass();

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

volatile MyClass c=new MyClass();

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