ConcurrentHashMap 1.7+1.8要点

前言

HashMap并不是线程安全,而Hashtable是在方法上加synchronized,相当于锁住整个table,因此锁粒度太大。读也加,写也加。读也加就是因为改写后,不能立刻刷新到主存中,因此ConcurrentHashMap才加了volatile以保证可见性。
注:Hashtable初始容量为11,负载因子也是0.75.翻倍时capacity*2+1。

分段锁的思想

HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率。

ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment继承了一种可重入锁ReentrantLock,在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个数组加链表结构的元素(HashMap 1.7底层就是Entry数组,两者结构相同), 每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。换言之,一个Segment相当于一个HashMap。

如何扩容

保持Segment也就是锁的个数不变,在Segment的HashEntry数组进行扩容。这里的扩容机制和1.7的HashMap一样。

如何保证了并发以及性能

上面提到,每一个Segment都是相当于一把锁,因此不同的Segment之间肯定是不会出现安全问题,那么如果是同一个Segment呢,因此,HashEntry和HashMap中的Entry在这里不同,对于值value和HashEntry都加上了volatile修饰,这样可以保证可见性,虽然 HashEntry 中的 value 是用 volatile 关键词修饰的,但是并不能保证并发的原子性,所以 put 操作时仍然需要加锁处理。然而get操作是没有加锁。这是因为加入volatile可以保证读到的永远是最新的数据。(可见性)

竞争锁

如果已经有线程拿到Segment锁, 就会自旋等待,scanAndLockForPut() 自旋获取锁。如果重试次数到达阈值,则变成阻塞锁等待。

下面介绍1.8的部分

Java 8 ConcurrentHashMap结构基本上和Java8的HashMap一样,不过保证线程安全性。

1.8的并发机制

jdk 1.8中ConcurrentHashMap的get操作全程不需要加锁,这也是它比其他并发集合如hashtable、用Collections.synchronizedMap()包装的hashmap;安全效率高的原因之一。这一点同jdk 1.7。

get操作全程不需要加锁是因为Node的成员val是用volatile修饰的,和数组Node用volatile修饰没有关系。
数组用volatile修饰主要是保证在数组扩容的时候保证可见性。这也同jdk 1.7。

但不同的是,这里的锁,粒度更小。原来是对需要进行数据操作的Segment加锁,现调整为对每个数组元素加锁(Node),使用的是同步代码块。也就是说,只有你对同一个元素进行修改时,才会认为发生冲突,显然粒度非常小了。
CAS是compare and swap的缩写,即我们所说的比较交换。cas是一种基于锁的操作,而且是乐观锁。

1.8 put

首先看key和value是否为null。为空抛异常。
然后看Map有没有初始化容量,比如是一个空map,那么初始化。
如果已经存在了map,就看对应的数组元素是否存在,不存在就用cas操作,将数据插入到数组。
否则,就说明有冲突,需要去链表中或者树上看看,因此此时需要加锁,似乎是对数组的某个元素(对应链表的头结点)进行加锁,然后去链表或者红黑树上去找插入的位置。

转换成红黑树是两个条件。一个是链表长度到8,一个是数组长度到64.

全部评论

相关推荐

08-14 11:30
门头沟学院 Java
失去了成为米孝子的机会
投递小米集团等公司10个岗位
点赞 评论 收藏
分享
算法题感觉都挺简单的啊
投递哔哩哔哩等公司10个岗位
点赞 评论 收藏
分享
这一生如履薄冰:产品经理现在都要会微调大模型了吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务