ConcurrentHashMap源码同步功能分析

1 ConcurrentHashMap的基本架构和关键方法

基本架构与HashMap一致,留出来的api也是,屏蔽了内部实现的复杂细节,主要的get,put方法是首先要看的,然后深入了是对应HashMap的扩容机制的tranfer方法,这个参见ConcurrentHashMap之transfer方法源码,桶槽等基本概念不再赘述,HashMap的扩容机制详解见HashMap扩容机制源码

2 操作的API get和put方法的同步机制

get方法作为读操作,Doug Lee大神在设计时并未给get方法加锁,基本逻辑与HashMap没有区别。
put方法作为写操作,是肯定需要同步操作的,而这里put操作加锁方式从JDK1.7的分段锁,到1.8的CAS+synchronized,是有较大变化的,我们以1.8为例来分析put操作的加锁原理。结论是:如果找到的对应位置的桶为空,则尝试CAS插入,否则用synchronized锁住头节点完成插入。具体细节见代码及注释

    final V putVal(K key, V value, boolean onlyIfAbsent) {
   
    	//不同于HashMap,CHM不准加入null作为key
        if (key == null || value == null) throw new NullPointerException();
        //计算对应hash值
        int hash = spread(key.hashCode());
        int binCount = 0;
        //死循环直到更新成功
        for (Node<K,V>[] tab = table;;) {
   
            Node<K,V> f; int n, i, fh;
            //如果没有初始化,则初始化,懒加载
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            //如果桶位置为空,则利用CAS操作更新
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
   
            	//这个CAS也是由Unsafe这个类提供的
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                   // no lock when adding to empty bin
            }
            //如果正在被扩容,则帮忙一起扩容
            else if ((fh = f.hash
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值