一文就懂ConcurrentHashMap实现原理

本文详细解析了ConcurrentHashMap在JDK1.7和1.8的实现原理,从分段锁到CAS+Synchronized的转变,以及从数组+链表到数组+链表+红黑树的数据结构优化,阐述了其在并发环境下的高性能设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ConcurrentHashMap介绍

哈希表就是一种以键-值(key -indexed) 存储数据的结构,我们只要输入待查 找的值即 key,即可查找到其对应的值。

哈希表是一种非常高效的数据结构 ,设计优良的哈希函数可以使其上的增删改查操作达到O(1)级别。Java为我们提供了一个现成的哈希结构 ,那就是HashMap类 ,在前面的文章中我曾经介绍过HashMap类 ,知道它的所有方法都未进行同步 ,因此在多线程环境中是不安全的。

为此 ,Java为我们提供了另外一个HashTable类 ,它对于多线程同步的处理非常简单粗暴 ,那就是在HashMap的基础上对其所有方法都使用synchronized关键字进行加锁。

例如下面截取的几个方法:

image-20221031152246595

这种方法虽然简单 ,但导致了一个问题 ,那就是在同一时间内只能由一个线程去操作哈希表。即使这些线程都只是进行读操作也必须要排队 ,这在竞争激烈的多线程环境中极为影响性能。本篇介绍的ConcurrentHashMap就是为了解决这个问题的 ,它的内部使用分段锁将锁进行细粒度化 ÿ

### ConcurrentHashMap 实现原理 #### 数据结构 ConcurrentHashMap 在 JDK 8 中采用了 `Node` 数组加链表和红黑树的方式来存储键值对。当哈希冲突发生时,会形成一条链表;如果链表长度超过一定阈值,则转换为红黑树以提高查找效率[^1]。 #### 并发控制机制 为了提升性能并减少锁竞争,ConcurrentHashMap 将整个映射分割成多个部分(称为段),通过调整并发级别参数可以改变这些段的数量,默认情况下有 16 个这样的段。每个段都相当于一个小的独立哈希表,并且拥有自己的锁对象。因此,在多线程环境下操作不同段的数据不会引起相互之间的阻塞等待现象,从而提高了整体吞吐量[^2]。 #### 原子更新操作 内部大量运用了无锁编程中的 CAS (Compare And Swap) 技术来进行高效的原子化修改动作,比如插入新节点或者替换已有条目等。CAS 是一种乐观锁定策略,它允许程序尝试执行某些变更而无需持有任何显式的互斥锁资源,只有当检测到预期条件满足时才会真正提交更改请求。 ```java // 示例代码展示如何使用 ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap; public class Example { private static final int CAPACITY = 1 << 4; public static void main(String[] args){ var map = new ConcurrentHashMap<String, String>(CAPACITY); // 插入数据项 map.put("key", "value"); // 获取指定 key 对应 value System.out.println(map.get("key")); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我心向阳iu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值