JDK 1.8ConcurrentHashMap 理解

1.8 currentHashMap不同于1.7 的分段加锁 、分段扩容,1.7虽然也能做到多线程并发的扩容,但是效率不高。
1.8currentHashMap 的put操作会对table (key,value)对应的索引位置上的元素检测,如果是空直接cas放置,否则进行加锁操作,这时候就可能是链上的放置 或者树上的放置。完成之后需要对整个currentHashMap 的元素个数加1,这时的操作类似longAdder 来进行多线程下的同步增加个数1,具体原理就是尝试性的进行cas+1操作,如果不成功则利用CounterCell 来进行+1操作,最后计数需要遍历countercell 中元素的值 得到和,竞争激烈的情况下提高了性能。同时应该确定增加后的currentHashMap 的元素是否超过了扩容阈值,来判断是否进行扩容。
扩容的操作相关的重要参数是sizeCTL ,sizeCtl 初始值为0,在initTable 之后设置为扩容阈值,所以我们在扩容的时候如果发现现在map中的元素个数大于等于阈值,则进行扩容操作,currentHashMap 是采用固定步长从后向前进行元素的转移,最先进行扩容的线程会将扩容完成的桶位置上放置forwardingNode 代表此位置转移完成但是 还没完成整体的转移,所以会一直向前遍历扩容,知道所有线程都完成了帮助扩容,这时才进行结束扩容设置newTab 进行使用。

所以会有这样的情况 你这个线程put时发现此时你放置的桶位置上的元素正在进行扩容,那么你只能放一放put然后进行帮助扩容操作,等到扩容完成后才能进行put。

我们应该知道1.7和1.8ConcurrentHashMap 有以下不同点?
1.7 采用分段锁 而1.8 放弃分段锁,使用synchronized
1.8 支持并发扩容,即真正的多线程操作同一个hashMap上的元素,直到整个hashMap 扩容完成。
1.7 统计数据元素是加锁统计每个segment,而1.8 是使用CounterCell 来增加激烈竞争下的 统计问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值