cha*_* ro 8 java concurrency hashmap concurrenthashmap java.util.concurrent
在JDK 1.6中,Doug Lea final在该next领域之前使用.
static final class HashEntry<K,V> {
final K key;
final int hash;
volatile V value;
final HashEntry<K,V> next;
Run Code Online (Sandbox Code Playgroud)
而在JDK 1.7中,next字段前面是volatile.我还注意到在JDK 1.7中,该get方法采用getObjectVolatile读取value字段的方法,该字段具有易失性加载语义.
我不知道Doug Lea之前使用过什么final.如果正确性存在问题,那么如何volatile在JDK 1.7(也是JDK 1.8)中替换它?
编辑:
具体来说,我的问题是我们可以final用volatileJDK 1.6的实现代替吗?
对于你的第一个问题:
我不明白为什么 Doug Lea 以前使用 Final。如果正确性有问题的话,那么他怎么可能在JDK 1.7(还有JDK 1.8)中将其替换为 volatile 呢?
这不是正确与否的问题。就线程安全而言,两种实现都是正确的。试图解决的问题是减少 CHM 的初始足迹。在 Java 6 中,将next字段设为 Final 需要创建至少带有占位符的对象。这导致了过多的空对象创建,因此进行了更改以提供“需要时创建”语义。
具体来说,我的问题是,我们可以在 JDK 1.6 的实现中将 Final 替换为 volatile 吗?
当然,只要操作继续保持顺序一致(它们确实如此)。
Doug Lea 的评论之一涉及到这一设计变更
/*
* ...
* Historical note: The previous version of this class relied
* heavily on "final" fields, which avoided some volatile reads at
* the expense of a large initial footprint. Some remnants of
* that design (including forced construction of segment 0) exist
* to ensure serialization compatibility.
*/
Run Code Online (Sandbox Code Playgroud)
那么,回答您可能会遇到的另一个问题,为什么final最初选择它?为了防止稍后出现一些不稳定的读取。