juc源码解读四(ConcurrentHashMap)

put方法

自旋方法;

initTable方法

initTable方法是个while循环,退出条件是数组初始化好了;返回值是初始化好的数组;
sizeCtl最开始的值
将sizeCtl赋值给了一个临时变量sc,两个作用
1)cas操作设置sizeCtl为-1前先判断sizeCtl是否还和sc相等,相等则cas操作可以成功,则可以初始化数组,即以临时变量作为比较依据;
2)存储sizeCtl被修改为-1之前的值,便于在将sizeCtl修改为-1后,判断第一个进入initTable方法的线程sizeCtl最初的大小;sizeCtl最初的大小与用户调用chm构造方法的方式有关,如果用户用的是chm的默认构造函数,则sizeCtl为0,后续将以16作为初始化数组的容量;若用的是有参构造,传入了chm数组“初始化容量x”,则此时在构造函数中会将sizeCtl赋值为不小于x+x/2+1的最小的2的次方数y,此值y才是真正的初始化数组容量;
初始化过程
假设最开始线程A,B同时进入initTable方法,此时的sizeCtl的值只有两种可能,为0或者为y(2的幂),当线程A,B同时进行cas修改sizeCtl为-1,若A线程修改成功,则线程B再次自旋,感知到sizeCtl为-1,则会执行Thread.yield()让出cpu时间片,进入就绪状态,下一刻线程B可能会重新抢到cpu执行权也可能没抢到。若没抢到,则线程A此时会根据sizeCtl初始化数组,随后将sizeCtl的值更新为0.75n(为下次扩容的阈值,达到该值就扩容),n为数组长度,最后退出循环;线程B再次拿到cpu执行权时,发现数组已经初始化好了,最后也退出;

判断(n-1)&hash(key)所在桶位头节点状态

一共有四种情况,如下
头节点为null
cas给该桶位添加一个头节点,cas失败则直接break退出put自旋;

存在头节点且其hash为-1
表示当前桶位是FWD节点,接着当前线程执行helpTransfer方法,协助table迁移数据至新的更大table;

存在头节点且其hash不小于0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orcharddd_real

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值