阿里十年架构师,教你深度分析ConcurrentHashMap原理分析

本文深入探讨了ConcurrentHashMap在Java中的应用和实现原理,包括其线程安全特性、JDK1.7与1.8版本的区别、put方法的五个阶段以及扩容策略。文章详细分析了ConcurrentHashMap的结构变化,如取消Segment分段、引入红黑树,以及如何通过并发扩容避免加锁带来的性能影响。

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

阿里十年架构师,教你深度分析ConcurrentHashMap原理分析

 

ConcurrentHashMap的初步使用及场景

CHM的使用

ConcurrentHashMap是J.U.C包里面提供的一个线程安全并且高效的HashMap,所以ConcurrentHashMap在并发编程的场景中使用的频率比较高,那么这一节课我们就从ConcurrentHashMap的使用上以及源码层面来分析ConcurrentHashMap到底是如何实现安全性的

 

api使用

ConcurrentHashMap是Map的派生类,所以api基本和Hashmap是类似,主要就是put、get这些方法,接下来基于ConcurrentHashMap的put和get这两个方法作为切入点来分析ConcurrentHashMap的源码实现

ConcurrentHashMap的源码分析

先要做一个说明,这节课分析的ConcurrentHashMap是基于Jdk1.8的版本。

JDK1.7和Jdk1.8版本的变化

ConcurrentHashMap和HashMap的实现原理是差不多的,但是因为ConcurrentHashMap需要支持并发操作,所以在实现上要比hashmap稍微复杂一些。

在JDK1.7的实现上,ConrruentHashMap由一个个Segment组成,简单来说,ConcurrentHashMap是一个Segment数组,它通过继承ReentrantLock来进行加锁,通过每次锁住一个segment来保证每个segment内的操作的线程安全性从而实现全局线程安全。整个结构图如下

 

阿里十年架构师,教你深度分析ConcurrentHashMap原理分析

 

 

当每个操作分布在不同的segment上的时候,默认情况下,理论上可以同时支持16个线程的并发写入。

相比于1.7版本,它做了两个改进

  1. 取消了segment分段设计,直接使用Node数组来保存数据,并且采用Node数组元素作为锁来实现每一行数据进行加锁来进一步减少并发冲突的概率
  2. 将原本数组+单向链表的数据结构变更为了数组+单向链表+红黑树的结构。为什么要引入红黑树呢?在正常情况下,key hash之后如果能够很均匀的分散在数组中,那么table数组中的每个队列的长度主要为0或者1.但是实际情况下,还是会存在一些队列长度过长的情况。如果还采用单向列表方式,那么查询某个节点的时间复杂度就变为O(n); 因此对于队列长度超过8的列表,JDK1.8采用了红黑树的结构,那么查询的时间复杂度就会降低到O(logN),可以提升查找的性能;

 

阿里十年架构师,教你深度分析ConcurrentHashMap原理分析

 

这个结构和JDK1.8版本中的Hashmap的实现结构基本一致,但是为了保证线程安全性,ConcurrentHashMap的实现会稍微复杂一下。接下来我们从源码层面来了解一下它的原理.

我们基于put和get方法来分析它的实现即可

put方法第一阶段

阿里十年架构师,教你深度分析ConcurrentHashMap原理分析

 

假如在上面这段代码中存在两个线程,在不加锁的情况下:线程A成功执行casTabAt操作后,随后的线程B可以通过tabAt方法立刻看到table[i]的改变。原因如下:线程A的casTabAt操作,具有volatile读写相同的内存语义,根据volatile的happens-before规则:线程A的casTabAt操作,一定对线程B的tabAt操作可见

initTable

数组初始化方法,这个方法比较简单,就是初始化一个合适大小的数组

sizeCtl这个要单独说一下,如果没搞懂这个属性的意义,可能会被搞晕

这个标志是在Node数组初始化或者扩容的时候的一个控制位标识,负数代表正在进行初始化或者扩容操作

-1 代表正在初始化

-N 代表有N-1有二个线程正在进行扩容操作,这里不是简单的理解成n个线程,sizeCtl就是-N,这块后续在讲扩容的时候

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值