首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JDK1.6和JDK1.7中ConcurrentHashMap的不同` `next`‘条目

JDK1.6和JDK1.7中ConcurrentHashMap的不同` `next`‘条目
EN

Stack Overflow用户
提问于 2015-07-15 12:05:08
回答 2查看 508关注 0票数 8

在JDK1.6中,Doug在final字段前面使用next

代码语言:javascript
复制
static final class HashEntry<K,V> {
    final K key;
    final int hash;
    volatile V value;
    final HashEntry<K,V> next;

而在JDK1.7中,next字段前面是volatile。我还注意到,在JDK1.7中,get方法使用getObjectVolatile方法读取具有易失性负载语义的value字段。

我不明白Doug之前为什么使用final。如果正确性有问题,那么他如何用JDK1.7(也是JDK1.8)中的volatile替换它?

编辑:

具体来说,我的问题是,在JDK1.6的实现中,我们能用final代替volatile吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-15 15:08:57

关于你的第一个问题:

我不明白Doug之前为什么会使用final。如果正确性有问题,那么他如何用JDK1.7(也是JDK1.8)中的易失性来替换它呢?

这不是一个正确的问题。这两种实现在线程安全方面都是正确的。正在努力解决的是减少CHM最初的足迹。在Java6中,要使next字段成为最终结果,就需要至少使用一个位置保持器来创建对象。这导致了过多的空对象创建,因此被更改为提供需要时的创建语义。

具体来说,我的问题是,在JDK1.6的实现中,我们是否可以用易失性替换final?

当然,只要这些操作是连续一致的,它们就是这样。

Doug的一个评论涉及到这个设计上的改变

代码语言:javascript
复制
 /* 
 * ...
 * 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. 
 */

因此,要回答另一个可能存在的问题,为什么最初选择了final?以防止稍后的易失性读取。

票数 2
EN

Stack Overflow用户

发布于 2015-07-15 13:08:22

这不是用volatile代替volatile的问题。和RealSkeptic一样,它在许多其他方法中也被改变了。其目的可能是对ConcurrentHashMap.remove()进行优化。在JDK1.6中,存储桶(按哈希代码分组的对象)的列表是CopyOnWrite,因此在remove()中复制列表的一部分,在JDK1.7中只更改next指针。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31429918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档