ConcurrentHashMap底层原理以及实现原理,还有基本功能,以及性能方面的优化


今天来和大家谈谈,ConcurrentHashMap ,我伴随着以下几个问题进行对它进行了解。
开干…

ConcurrentHashMap 为什么是线程安全的?

JDK1.8之后的ConcurrentHashMap

在JDK1.8版本中采用了CAS+synchronized的方法来保证并发,线程安全

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

这个问题我从这三个方面来回答:

ConcurrentHashMap 的整体架构、ConcurrentHashMap 的基本功能、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 实现原子递增。它的核心思想是引入了数组来实现对并发更新的负载。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ConcurrentHashMap的底层实现原理是基于分段锁(Segment)和哈希表(HashEntry)的数据结构。每个Segment都是一个独立的哈希表,内部包含一个HashEntry数组,用来存储键值对。在Java 8之前的版本中,ConcurrentHashMap的实现与Java 7相同。然而,从Java 8开始,ConcurrentHashMap的实现方式有所改变。 具体来说,在Java 8中,ConcurrentHashMap使用了一种称为"数组+链表+红黑树"的数据结构来存储键值对。底层的哈希表被分割成多个Segment,每个Segment都有自己的锁。这样可以实现更高的并发性,因为每次只需要锁住一个Segment,而不是整个哈希表。 当我们需要执行get操作时,首先根据键的哈希值定位到对应的Segment,然后再在该Segment的哈希表中进行查找。如果有多个键映射到同一个Segment,那么会在该Segment中的链表或红黑树中进行进一步的查找。通过这种方式,可以提高查找效率。 总之,ConcurrentHashMap通过分段锁和哈希表的结构,实现了高效的线程安全的并发操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ConcurrentHashMap 底层原理](https://blog.csdn.net/qq_37967783/article/details/131095252)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ConcurrentHashMap底层结构和原理详解](https://blog.csdn.net/qq_45408390/article/details/122189726)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值