ConcurrentHashMap 并发扩容骚操作

本文探讨了ConcurrentHashMap的扩容操作,包括触发扩容的条件,如元素个数达到阈值、putAll方法及链表长度超过特定值。在统计元素个数时,使用类似LongAdder的策略,通过CounterCell数组和BASECOUNT配合实现并发计数。扩容过程由各线程负责至少16个槽的迁移,并保证在扩容期间仍能对外提供读写服务。最后,推荐了一篇源码分析文章供进一步学习。
摘要由CSDN通过智能技术生成

上期问题
少年,老衲看你骨骼清奇,眉宇之间透露着一股王者的气息。来吧,跟我讲讲 ConcurrentHashMap 是如何进行管理它的容量的,也就是当我们调用它的 size 方法的时候发生了什么故事?(前面我们介绍了 ConcurrentHashMap 的实现原理,但是扩容和容量大小留了个小尾巴,今天来割一下这个小尾巴,嘿嘿)

我的答案
毕竟是要支持并发,ConcurrentHashMap 的扩容操作比较复杂,我们将从以下几点来带讨论一下它的扩容。

触发扩容

  1. 添加新元素后,元素个数达到扩容阈值触发扩容。

  2. 调用 putAll 方法,发现容量不足以容纳所有元素时候触发扩容。

  3. 某个槽内的链表长度达到 8,但是数组长度小于 64 时候触发扩容。

统计元素个数

触发后面 2 点没啥问题,但是第 1 点中有个小问题,它是如何统计元素的个数呢?它采用和 LongAdder类似的分散热点数据的解决思路,不知道 LongAdder 的小伙伴可以参考往期文章 还在用 AtomicLong?是时候了解一下 LongAdder 了。ConcurrentHashMap 内部定义了一个 CounterCell 的类,它同样被 Contended 修饰防止 volatile 带来的伪共享问题,伪共享不了解可以参考往期文章 面试官问我 volatile 是否存在伪共享问题?我懵逼了。内部实例化了一个 CounterCell 的数组来记录元素的个数,每当线程 put 一个元素到容器中,线程会被映射到一个 CounterCell 的一个元素上面采用 CAS 算法进行加 1 操作,当然如果当前 CounterCell 上已经有线程在

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值