ConCurrentHashMap1.8 put,size,get过程

put

1.先对传入的key和value判断是否为空,为空就抛出异常。
2.通过spread方法计算hash值,然后进入for循环。
3.判断table是否为null或者长度为0,如果是,调用initTable进行初始化。
4.else if中根据key的哈市值判断是否有Node节点,如果没有则使用CAS进行添加。
5.在下一个else if中判断是否节点的hash值等于MOVED,如果是就调用helpTransfer方法帮助扩容。
6.如果以上的else if条件都不满足,就会进入else语句块。else语句块中会对一个node节点加锁,然后分两部分操作,一部分是链表部分一部分是树部分。如果是Node(链表结构)则执行链表的添加操作;使用instanceof判断当前节点是不是TreeBin,如果是TreeNode(树型结构)则执行树添加操作。
7、判断链表长度已经达到临界值8(默认值),当节点超过这个值就需要把链表转换为树结构。调用treefiyBin方法。
8、如果添加成功就调用addCount()方法统计size,并且检查是否需要扩容

get

1.计算hash值,调用spread函数,定位到该table索引位置,如果是首节点符合就返回。

2.以上都不符合的话,就往下遍历节点,匹配就返回,否则最后就返回null

size

size方法会调用sumCount方法,其中有两个重要的变量,一个是CounterCell数组对象,一个CounterCell对象,一个是有volatile 修饰的baseCount变量,他会把该baseCount变量赋值给sum变量,当进行put或remove操作时,会调用addCount方法,更新baseCount。除此之外,还有个叫CounterCell的变量,在并发环境下对baseCount修改时,有的线程可能修改失败,那么就创建这个对象并将1这个值插入该对象中,所以当它判断这个数组对象不为null的时候,开始遍历数组,做sum累加,sum+=a.value

会在三个地方触发扩容

1.putval方法最后调用addCount方法时,内部会判断是否元素个数达到扩容阈值,如果是就调用transfer方法扩容。
2.在put操作时,链表节点达到8,数组长度为64的时候,会调用tryPresize方法扩容。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值