Java学习笔记(二)ConcurrentHashMap

网上研究ConcurrentHashMap的帖子多如牛毛,有几篇不错,推荐一下:

  - IBM developerWorks 探索 ConcurrentHashMap 高并发性的实现机制 

  - skywang12345的博客  Java多线程系列--“JUC集合”04之 ConcurrentHashMap


几个要点:

1. 通过将哈希表拆分成多个片段(Segment)实现“锁分段”,用多个小锁取代一个大锁,减少冲突

2. 内部数据尽量定义为 final, 或volatile, 并利用sun.misc.Unsafe,实现对读操作不需要加锁即可进行并行操作

    //TODO 需要继续研究sun.misc.Unsafe

3. 用链表处理哈希碰撞的情况,通过copy元素 + 修改bucket引用的方式,使得在修改的时候,不影响已经开始的读取操作(读到的可能为修改之前的值)。

    这一点在上面推荐的两篇文章中有详细介绍。

4. power-of-two for HashMap buckets

    关于哈希处理部分,推荐两篇帖子

    HashMap requires a better hashCode() - JDK 1.4 Part II

    从头到尾彻底解析Hash表算法


CurrentHashMap的数据结构如下图



最后记录几个读源码时候的几个点,便于复习

1、Segment的数量,不小于concurrentLevel的最小的2的幂。每个Segment中的哈希表长度是是2的幂。Threashold是当前哈希表中最多容纳的HashEntry数量,如果超过,哈希表长度*2,rehash

2、为避免所存储的key的hash值导致大量碰撞,对原始hash值再进行一次hash,详见hash()方法。源码中注释如下:

    /**
     * Applies a supplemental hash function to a given hashCode, which
     * defends against poor quality hash functions.  This is critical
     * because ConcurrentHashMap uses power-of-two length hash tables,
     * that otherwise encounter collisions for hashCodes that do not
     * differ in lower or upper bits.
     */


3、根据hash值的最高n位来定位segment: (hash >>>segmentShift ) & segmentMask

4、注意下面这个判断条件,用到集合,千万要保证 hash()方法 和 equals() 的一致性

if ((k = e.key) == key || (e.hash == h && key.equals(k)))

5、要理解透彻,相关的知识、代码要多看,例如:非公平锁,哈希算法,Volatile,Unsafe,内存模型等等


最后,看代码遇到一个问题:

大量的文档中都提到:HashEntry的key, hash, next都是final的,但我读的 JDK 7u55的代码,next属性是volatile. 并且,在CHM的源码中,对next属性只有read,没有write,那么修饰符改为volatie的目的何在呢?


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值