ConcurrentHashMap 底层具体实现知道吗?实现原理是什么?

之前分享过一期 HashMap 的面试题,然后有个小伙伴私信我说,他遇到了一个ConcurrentHashMap 的问题不知道怎么回答。
于是,就有了这一期的内容!!
我是 浮生,一个工作了 14 年的 Java 程序员,
今天我来分享关于  ”ConcurrentHashMap 底层实现原理“ 这个问题

一、问题解析

这个问题我从这三个方面来回答:
1. ConcurrentHashMap 的整体架构
2. ConcurrentHashMap 的基本功能
3. ConcurrentHashMap 在性能方面的优化
ConcurrentHashMap 的整体架构
(如图所示),这个是 ConcurrentHashMap 在 JDK1.8 中的存储结构,它是由数组、单向链表、红黑树组成。

当我们初始化一个ConcurrentHashMap实例时,默认会初始化一个长度为16的数组。由于 ConcurrentHashMap 它的核心仍然是 hash 表,所以必然会存在 hash 冲突问题。 ConcurrentHashMap 采用链式寻址法来解决 hash 冲突。当 hash 冲突比较多的时候,会造成链表长度较长,这种情况会使得ConcurrentHashMap 中数据元素的查询复杂度变成 O(n )。因此在 JDK1.8 中,引入了红黑树的机制。当数组长度大于 64 并且链表长度大于等于 8 的时候,单项链表就会转换为红黑树。另外,随着 ConcurrentHashMap 的动态扩容,一旦链表长度小于 8,红黑树会退化成单向链表。
ConcurrentHashMap 的基本功能
ConcurrentHashMap 本质上是一个 HashMap,因此功能和 HashMap 一样,但是 ConcurrentHashMap 在 HashMap 的基础上,提供了并发安全的实现。并发安全的主要实现是通过对指定的 Node 节点加锁,来保证数据更新的安全性(如图所示)。

ConcurrentHashMap 在性能方面做的优化
如果在并发性能和数据安全性之间做好平衡,在很多地方都有类似的设计,比如 cpu的三级缓存、mysql 的 buffer_pool、Synchronized 的锁升级等等。ConcurrentHashMap 也做了类似的优化,主要体现在以下几个方面:
在 JDK1.8 中,ConcurrentHashMap 锁的粒度是数组中的某一个节点,而在JDK1.7,锁定的是 Segment,锁的范围要更大,因此性能上会更低。
引入红黑树,降低了数据查询的时间复杂度,红黑树的时间复杂度是 O( logn )。
(如图所示),当数组长度不够时,ConcurrentHashMap 需要对数组进行扩容,在扩容的实现上,ConcurrentHashMap 引入了多线程并发扩容的机制,简单来说就是多个线程对原始数组进行分片后,每个线程负责一个分片的数据迁移,从而提升了扩容过程中数据迁移的效率。
ConcurrentHashMap 中有一个 size()方法来获取总的元素个数,而在多线程并发场景中,在保证原子性的前提下来实现元素个数的累加,性能是非常低的。
ConcurrentHashMap 在这个方面的优化主要体现在两个点:
当线程竞争不激烈时,直接采用 CAS 来实现元素个数的原子递增。
如果线程竞争激烈,使用一个数组来维护元素个数,如果要增加总的元素个数,则直接从数组中随机选择一个,再通过 CAS 实现原子递增。它的核心思想是引入了数组来实现对并发更新的负载。

以上就是我对这个问题的理解!

二、总结

从以上回答可以看到,ConcurrentHashMap 里面有很多设计思想值得学习和借鉴。
比如锁粒度控制、分段锁的设计等,它们都可以应用在实际业务场景中。很多时候大家会认为这种面试题毫无价值,当你有足够的积累之后,你会发现从这些技术底层的设计思想中能够获得很多设计思路。
本期文章就到这里结束了,喜欢的朋友记得点赞收藏。
另外,我也陆续收到了很多小伙伴的面试题,我会在后续的内容中逐步更新给到大家!
我是 浮生,一个工作了 14 年的 Java 程序员,咱们下期再见。

 

三、粉丝福利

最近很多同学问我有没有java学习资料,我根据我从小白到架构师多年的学习经验整理出来了一份 50W字面试解析文档、简历模板、学习路线图、java必看学习书籍 、需要的小伙伴 可以关注我的
 
公众号:“ 灰灰聊架构 ”, 回复暗号:“ 321 ”即可获取
 

 

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值