concurrentHashMap源码略读

由于项目中常用的集合是hashMap和conCurrentHashMap,hashMap的源码之前已经写过  ,今天看下conCurrentHashMap的存取和两者之间的一些比较。

    conCurrentHashMap(jdk1.7和1.8的变化)

 在jdk1.7以及之前ConcurrentHashMap采用的是Segment+HashEntry的分段锁策略进行设计的 ,Segment继承 了可重入锁,在1.8中改变了这一设计  将HashEntry改为和HashMap一样的Node节点 作为基本变量  还是数组+链表+红黑树的设计手法。

concurrentHashMap源码略读_第1张图片

在这张图片 的注释中可以看到 在一个hash槽存放8个节点的可能性为小于百万分之一,所以节点个数一般按7为分界线 将小于7(小于6退化为链表),大于等于8存放到红黑树中。

concurrentHashMap源码略读_第2张图片

concurrentHashMap源码略读_第3张图片

首先根据传入的key进行hash运算找到对应的链表节点或者说红黑树节点(都是用Node存的) 对当前链表节点进行判断key,如果key和key'的hash运算都是相同的 ,那就说明是要替换掉这个值 如代码中,直接将值进行更新,否则 将整个节点替换到当前节点的next。在此之前首先要先判断是否要进行扩容 以为concurrentHasmap和HashMap一样有加载因子和初始容量。

helpTransfer这个方法是进行重组的方法 往里看的话 再存入节点的循环中也对节点加了synchronized进行加锁处理,保证并发状态下的线程安全。  因为HashMap线程不安全也是因为存值的时候扩容有可能导致链表的内循环。

取值相对简单 跟hashMap差别不大,读取值不需要加锁。

有个疑问是为什么ConcurrentHashMap不使用Lock进行加锁  而是使用synchronized?

你可能感兴趣的:(java,源码,java,hashmap)