在java4和java5之后使用volatile keyword
有什么不同?
与此相关,
非原子变量(long / double)的读/写操作是原子的 宣称为不稳定。
这对于java4 还是也是如此,它从java5开始有效???
答案 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或之前。