ConcurrentHashMap源码解析(二)之------put()方法。

文章详细介绍了ConcurrentHashMap的put()方法的执行流程,包括检查key和value是否为空,使用spread()方法进行寻址,判断桶位状态,处理链表或红黑树,并发控制以及扩容机制。通过对不同情况的判断,如桶位为空、扩容标志、链表或红黑树的插入,展示了ConcurrentHashMap在高并发下的性能和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ConcurrentHashMap是一个支持高并发集合,常用的集合之一。
而put()方法是并发里面的重点。

put()方法入口:

    public V put(K key, V value) {
   
        return putVal(key, value, false);
    }

1.hashMap是允许key和value都为空的;而在ConcurrentHashMap中是不允许的

  if (key == null || value == null) throw new NullPointerException();

2.通过spread()方法,可以让高位也能参与到寻址运算

   int hash = spread(key.hashCode());

3.binCount的作用是:在桶位中的所属链表的下标位置;
0表示当前桶位为null, node可以直接放着;
2 表示当前桶位已经树化为红黑树

    int binCount = 0;

4.进入自旋方法,定义的属性;

  // f 表示 桶位的头节点
            Node<K,V> f;
            // n  表示散列表数组长度
            // i 表示key通过寻址计算后,得到的桶位下标
            // fn 表示桶位头节点的hash值
            int n, i, fh;

5接下来就是四种情况的if判断
CASE1: 条件成立表示当前map中的table尚未初始化;

 if (tab == null || (n = tab.length) == 0)
                // 需要初始化
                tab = initTable();

6.这里又涉及到了initTable()方法,主要是使用CAS原理。
tab:表示map.table的引用

    Node<K,V>[] tab;

sc:表示临时局部的sizeCtl值

     int sc;

判断table为null,当前散列表尚未初始化;

(tab = table) == null || tab.length == 0

当sizeCtl < 0 ,大概率为-1,其他线程正在进行创建table的过程,当前线程没有竞争到初始化table的锁。

再次判断table为null,防止其他线程已经初始化完毕,然后当前线程再次初始化,导致数据丢失。

(tab = table) == null || tab.length == 0

最终赋值给map.table

table = tab = nt;

并给sc赋值,下次扩容的触发条件

 sc = n - (n >>> 2);

下面进入CASE2:
i=(n-1) &hash 表示key使用路由寻址算法得到key 对应table数组的下标位置;
f :tabAt获取指定桶位的头结点

(f = tabAt(tab, i = (n - 1) & hash)) == null

进入到CASE2代码块前置条件:当前table数组i桶位是null时;
使用CAS方式,设置指定数组i桶位为Node,且期望值为null时,
CAS操作成功,直接break
CAS操作失败,表示当前线程之前,有其他线程先进入向指定i桶位设置值了;

 if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

virtuousOne

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

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

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

打赏作者

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

抵扣说明:

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

余额充值