ConcurrentHashMap分析

对ConcurrentHashMap的改造

jdk8对ConcurrentHashMap进行脱胎换骨的改造,使用大量的lock-free技术来减轻因锁的竞争而对性能造成的影响,涉及volatile,CAS,锁,链表,红黑色等众多知识点

jdk8版本的ConcurrentHashMap进行分析,它对jdk7进行版本改造了三点改造

  • 取消分段锁机制,进一步降低冲突概率
  • 引入红黑树结构,同一个哈希槽上的元素超过一定阀值(8)后,单向链表改为红黑树
  • 使用了更加优化的方式统集合内的元素数量。首先,Map原有的size()方法最大只能表示2的31次方-1,ConcurrentHashMap额外提供了mappingCount(),用来返回集合内的元素数量,最大可以到达2的63次方-1,在元素更新时,使用了CAS和多种优化以提高并发能力

ConcurrentHashMap结构

数组存储结构分为两种:链表和红黑树。
(1)当某个槽内的元素超过8且table的容量大于或等于64时,由链表转为红黑树。
(2)当某个槽内的元素减少到6时,则由红黑素转换为链表。
(3)需要注意当table容量小于64只会扩容,并不会转换成红黑树
(4)再转换过程中,使用同步块锁住当前槽的首元素,防止其他进程对当前槽进行操作,转换完成后利用CAS替换原有链表(因为treeBin也存了next的引用,所以红黑树转链表变得非常简单,从TreeBin的first元素开始遍历所有节点,把节点从TreeNode转为Node即可)


链表转红黑树

在这里插入图片描述

触发上图主要操作时增加元素,即put()方法,基本思想与hashMap一致


扩容流程示意图

在这里插入图片描述


size()方法的优化

借助basrCount和countCells两个属性,并多次配合使用CAS方法,jdk8中的CouncurrentHashMap避免了锁的使用,思路分为:

  • 当并发量少时,优先使用CAS的方式直接更新baseCount
  • 如果更新base冲突,则认为会进入到比较激烈的竞争状态,通过启用counterCells减少竞争,通过CAS的方式把总数更新情况记录在conterCells对应的位置上
  • 如果更新counterCells上某个对应的位置出现了多次失败,则会通过扩容counterCells的方式减少冲突
  • 当conterCells处在扩容期间时,会尝试更新baseCount值

对于总数的统计,自需要让baseCount加上各个counterCells内的数据,就可以得出哈希内的元素总素,整个过程不需要借助锁。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值