Java基础复习---ConcurrrentHashMap

1、jdk1.7 中的ConcurrrentHashMap
在jdk1.7中,ConcurrrentHashMap采用分段锁机制,实现并发的更新操作,底层采用数组 + 链表的存储结构,其核心组件是 静态内部类Segment 和 HashEntry。
(1、Segment 继承ReentrantLock 用来充当锁的角色,每个Segment 对象守护每个散列映射表的若干个桶。
(2、HashEntry 是用来封装映射表的键值对;
(3、每个桶是由若干个HashEntry 对象链接起来的链表。
一个ConcurrentHashMap实例中包含由若干个Segment对象组成的数组,下面我们通过一个图来演示一下ConcurrentHashMap的结构:

在这里插入图片描述
2、在jdk1.8 中已经抛弃了分段锁的机制,采用CAS + 同步机制来保证并发更新的安全,底层采用数组+链表+红黑树的存储结构。JDK1.8版本的ConcurrentHashMap的数据结构已经接近HashMap,相对而言,ConcurrentHashMap只是增加了同步的操作来控制并发,从JDK1.7版本的ReentrantLock + Segment + HashEntry,到 JDK1.8 版本中synchronized + CAS + HashEntry + 红黑树,比较如下:

JDK1.8的实现降低锁的粒度,JDK1.7版本锁的粒度是基于Segment的,包含多个HashEntry,而JDK1.8锁的粒度就是HashEntry(首节点)。

JDK1.8版本的数据结构变得更加简单,使得操作也更加清晰流畅,因为已经使用synchronized来进行同步,所以不需要分段锁的概念,也就不需要Segment这种数据结构了,由于粒度的降低,实现的复杂度也增加了。

JDK1.8使用红黑树来优化链表,对于长度很长的链表的遍历是一个很漫长的过程,而红黑树的遍历效率是很快的,代替一定阈值的链表,这样形成一个最佳拍档。

JDK1.8为什么使用内置锁synchronized来代替重入锁ReentrantLock,以下几点:

因为粒度降低了,在相对而言的低粒度加锁方式,synchronized并不比ReentrantLock差,在粗粒度加锁中ReentrantLock可能通过Condition来控制各个低粒度的边界,更加的灵活,而在低粒度中,Condition的优势就没有了。

JVM的开发团队从来都没有放弃synchronized,而且基于JVM的synchronized优化空间更大,使用内嵌的关键字比使用API更加自然。在大量的数据操作下,对于JVM的内存压力,基于API的ReentrantLock会开销更多的内存,虽然不是瓶颈,但是也是一个选择依据。

猜你喜欢

转载自blog.csdn.net/weixin_43352448/article/details/87947105