在java4和java5中使用volatile关键字

时间:2012-04-26 14:55:44

标签: java

在java4和java5之后使用volatile keyword有什么不同?

与此相关,

  

非原子变量(long / double)的读/写操作是原子的   宣称为不稳定。

这对于java4 还是也是如此,它从java5开始有效???

4 个答案:

答案 0 :(得分:4)

是的,有区别 编译器可以针对任何先前的读取或写入重新排序Java 4 volatile,从而导致细微的并发错误,例如无法实现double check锁定(单身人士常用的惯用语) 这在Java 5.0中得到修复,它扩展了volatile的语义,不再对任何后续读取或写入进行重新排序,并引入了新的内存模型。您可以阅读此Double Checked Locking作为示例参考

答案 1 :(得分:3)

此网站对差异进行了很好的解释:http://www.javamex.com/tutorials/synchronization_volatile.shtml

他们还在单独的页面上解释了Java 5中volatile的行为:http://www.javamex.com/tutorials/synchronization_volatile_java_5.shtml

答案 2 :(得分:3)

人们提出了好的观点和参考,回答了我的问题,回答了第一部分。

具体到问题的第二部分,我在一些论坛上读到:

  

在某种意义上,声明为long的volatile也是原子的(在Java之前也是如此)   它保证(对于所有JVM实现)读或写   直接到主存储器而不是两个32位寄存器。

  

Pre-Java 5,volatile 假设长期提供这样的保证   并加倍。然而事情并没有在实践中以这种方式发挥作用   实施经常违反此保证。我记得   问题似乎在JDK 1.4附近得到修复,但仍然如此   在整个内存模型上工作的东西,他们并没有真正做到   关于它的明确公告直到JDK 5,当新规则出现时   宣布,记忆保证实际意味着什么。

这来自 Java语言规范,第二版

  17.4双重和长期的非原子性治疗

     

对volatile变量的加载,存储,读取和写入操作是原子的,   即使变量的类型是double或long。

答案 3 :(得分:0)

在java4和java5之后使用volatile关键字有什么区别?

JDK5之前的JMM被破坏,并且对JDK4使用volatile可能无法提供预期的结果。有关详情,请查看: http://www.ibm.com/developerworks/library/j-jtp02244/

非原子变量(long / double)的读/写操作在声明为volatile时是原子的。

long / double的读/写发生在两个独立的32位操作中。对于两个线程,一个线程可能读取更高的32位,而另一个线程读取长/双变量的低32位。简而言之,读取/写入long不是原子操作,与其他原语不同。 使用volatile for long / double应该提供这样的保证,因为volatile的指令不会被编译器重新排序用于易失性读/写,而volatile也提供可见性保证。但同样它可能不适用于JDK 4或之前。