ConcurrentHashMap底层结构分析

jdk1.7的ConcurrentHashMap

  • 底层数据结构: 分段的数组+链表。ConcurrentHashMap是由Segment数据结构和HashEntry数据结构组成。Segment实现了ReentrantLock,所以Segment是一种可重入锁,扮演锁的角色。HashEntry用于存储键值对数据。一个ConcurrentHashMap包含一个Segment数组。Segment数组中的每个元素包含一个HashEntry数组,HashEntry数组中的每个元素是一个链表结构的元素。Segment数组的每个元素各守护着一个HashEntry数组中的素有元素。当对HashEntry数组的数据进行修改时,必须首先获得对应的Segment数组元素的锁。
    在这里插入图片描述

  • 实现线程安全的方式: 首先将数据分为一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问,提高并发访问率。

jdk1.8的ConcurrentHashMap

  • 底层数据结构: ConcurrentHashMap取消了Segment分段锁,采用CAS(Compare-and-Swap,比较并替换)和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似, 是数组+链表/红黑树。(jdk1.6以后对synchronized锁做了很多优化,比如偏向锁、轻量级锁、自旋锁、锁消除、锁粗化等)
  • 实现线程安全的方式:
    在jdk1.7的时候,ConcurrentHashMap采用分段锁,对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分,多线程访问容器里不同数据段的数据,就不会产生锁竞争,提高并发访问率。
    到了jdk1.8的时候 ,synchronized只锁定当前链表或者红黑树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。

jdk1.8的ConcurrentHashMap(TreeBin:红黑树节点;Node:链表节点)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_47768542/article/details/109094878