下面我会详细讲解“ConcurrentHashMap 存储结构源码解析”的完整攻略。
ConcurrentHashMap 存储结构源码解析
一、ConcurrentHashMap 的概述
ConcurrentHashMap 是 JDK 中一个并发访问的哈希表,它提供了线程安全的哈希表访问功能,适用于高并发场景。ConcurrentHashMap 基于分段锁(Segment)实现并发访问。在 JDK1.7 中,ConcurrentHashMap 使用分段锁的机制来控制对不同 Segment 的访问,在 JDK1.8 中采用了更加优秀的 CAS+Synchronized 实现方式,以提高并发的性能。
二、ConcurrentHashMap 的内部结构
1. ConcurrentHashMap 存储结构
ConcurrentHashMap 的存储结构是一个数组和若干个 Segment。其中,数组是 ConcurrentHashMap 的主体,而 Segment 则是对数组中每个元素(也就是每一个 hash 桶)进行加锁,实现并发控制的机制。
因此,ConcurrentHashMap 的存储结构可以形象地描述为:一个数组 + 多个锁。
2. Segment 存储结构
在 JDK1.7 中,ConcurrentHashMap 使用分段锁的机制来实现多线程并发访问是,每个 Segment 维护着一个 HashEntry 数组,每一个 HashEntry 对象就是一个映射的键值对,其中键值对主要包括三个属性:Key、Value 和 next。
在 JDK1.8 中,ConcurrentHashMap 引入了 CAS+Synchronized 的机制,废除了 Segment,所以其存储结构也相应的被修改了。在 JDK1.8 的 ConcurrentHashMap 中,数组的每个元素不再是一个链表,而是一个数据集合,这个数据集合是一个桶,里面存储了多个映射的键值对,称之为 Node,其中 Node 存储了四个属性:hash、key、value 和 next。
3. ConcurrentHashMap 存储结构示例
下面对 ConcurrentHashMap 的存储结构进行示例说明。假设桶的数量为 16,其中每个桶使用链表来存储多个映射的键值对。在 JDK1.7 中,ConcurrentHashMap 的存储结构如下:
ConcurrentHashMap
+- Segment
| +- HashEntry 0
| +- HashEntry 1
| +- ...
| +- HashEntry N
+- Segment
| +- HashEntry 0
| +- HashEntry 1
| +- ...
| +- HashEntry N
+- ...
在 JDK1.8 中,ConcurrentHashMap 的存储结构如下:
ConcurrentHashMap
+- Node 0
| +- Node 1.1
| +- Node 1.2
| +- ...
| +- Node 1.N
+- Node 1
| +- Node 2.1
| +- Node 2.2
| +- ...
| +- Node 2.N
+- ...
三、ConcurrentHashMap 的线程安全实现
ConcurrentHashMap 的线程安全实现主要是通过加锁和同步机制来实现的。
1. JDK1.7 中 ConcurrentHashMap 的线程安全实现
在 JDK1.7 中,ConcurrentHashMap 使用分段锁的机制来实现对不同哈希桶的访问的并发控制。ConcurrentHashMap 中维护了一个名为 segments 的数组,每个元素为一个 Segment 对象,每个 Segment 维护着一个 HashEntry 数组,每一个 HashEntry 对象就是一个映射的键值对,其中键值对主要包括三个属性:Key、Value 和 next。
在 JDK1.7 中,ConcurrentHashMap 访问哈希表时,首先根据 Key 计算出其 hash 值,然后根据 hash 值求取其对应的 Segment 对象,最后进一步获取 Key 对应的 HashEntry,进行添加、删除和查询等操作。
在并发控制方面,JDK1.7 的 ConcurrentHashMap 维护了一个名为 "segments" 的数组,每个元素都是一个 Segment 对象,每个 Segment 对象实现了自己的加锁和解锁操作。并发访问时,每个线程会联系一个 ThreadLocal 变量,从而获取一个独立的 HashEntry。这样做可以避免不必要的竞争,提高并发效率。
2. JDK1.8 中 ConcurrentHashMap 的线程安全实现
在 JDK1.8 中,ConcurrentHashMap 引入了 CAS+Synchronized 机制,废除了 Segment,所以其线程安全实现也相应的被修改了。
在 JDK1.8 的 ConcurrentHashMap 中,数组的每个元素不再是一个链表,而是一个数据集合,这个数据集合是一个桶,里面存储了多个映射的键值对,称之为 Node,其中 Node 存储了四个属性:hash、key、value 和 next。多个线程可以同时访问同一个桶,但是对同一个 Node 的访问是需要同步的。
在并发控制方面,JDK1.8 中 ConcurrentHashMap 采用 CAS+Synchronized 机制来控制对同一个桶(即数组的一个元素)的访问。具体来说,在添加节点时,首先在对应的节点位置失败的尝试使用 CAS 添加,如果尝试失败,则采用 Synchronized 机制。
结尾
以上就是对 ConcurrentHashMap 存储结构源码解析的完整攻略,内容包括了 ConcurrentHashMap 的概述、内部结构、线程安全实现等方面,其中还包含了 JDK1.7 和 JDK1.8 两个版本的实现示例,希望对读者有所帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ConcurrentHashMap 存储结构源码解析 - Python技术站