ConcurrentHashMap核心方法分析(简略版)

ConcurrentHashMap中,其底层实现在JDK7和JDK8中是完全不同的,JDK8采用的是数组+链表+红黑树的方式来实现数据插入,其步骤为,维护一个元素为链表的数组,在插入键值对的过程中,如果某一个元素中,链表的长度大于8,则把链表转换为红黑树的形式来保存数据,这样可以加快对ConcurrentHashMap元素的查找过程,避免了线性遍历链表的操作。


再说到JDK7和JDK8中的区别,JDK8取消了JDK7中分段锁的概念,直接使用synchronized+CAS的方式来进行加锁,可能原因是由于在JDK8中,synchronized的底层实现对比以前有了很大的性能提升,目前synchronized和Reentrantlock的性能的差距已经很小。所以取消了分段锁的概念。


关于分段锁,其实就是普通的并发方法只有一个锁,所有的线程都在抢占这一个锁的资源,分段锁则是引入了多个锁,其实就是类似于线程池的实现原理理,可以同时实现多个线程一起工作,但缺点便是加剧了程序的复杂性和消耗更多的内存、CPU资源。

下面我们以JDK8中的ConcurrentHashMap类中的putVal方法来演示一下:

final V putVal(K var1, V var2, boolean var3) {
        if (var1 != null && var2 != null) {
		    //计算hash值,在数组中的槽位
            int var4 = spread(var1.hashCode());
            int var5 = 0;
			//获取所有节点的数组var6
            ConcurrentHashMap.Node[] var6 = this.table;

            while(true) {
                int var8;
				//如果为空,初始化节点数组,把初始化后的值赋给var6
                while(var6 == null || (var8 = var6.length) == 0) {
                    var6 = this.initTable();
                }

                ConcurrentHashMap.Node var7;
                int var9;
				//获取插入节点var7,如果hash表中不存在对应的k值,直接插入
                if ((var7 = tabAt(var6, var9 = var8 - 1 & var4)) == null) {
                    if (casTabAt(var6, var9, (ConcurrentHashMap.Node)null, new ConcurrentHashMap.Node(var4, var1, var2, (ConcurrentHashMap.Node)null))) {
                        break;
                    }
                } else {
				//如果hash表中存在对应的k值
                    int var10;
					//有别的线程正在扩容,当前线程帮忙一起扩容
                    if ((var10 = var7.hash) == -1) {
                        var6 = this.helpTransfer(var6, var7);
                    } else {
                        Object var11 = null;
						//以当前节点对象为锁,锁住当前线程
                        synchronized(var7) {
                            if (tabAt(var6, var9) == var7) {
							//通过当前节点hash值来判断是红黑树,还是链表
                                if (var10 < 0) {
								//如果当前节点是红黑树,按照红黑树节点插入,替换key值相同的对象
                                    if (var7 instanceof ConcurrentHashMap.TreeBin) {
                                        var5 = 2;
                                        ConcurrentHashMap.TreeNode var18;
                                        if ((var18 = ((ConcurrentHashMap.TreeBin)var7).putTreeVal(var4, var1, var2)) != null) {
                                            var11 = var18.val;
                                            if (!var3) {
                                                var18.val = var2;
                                            }
                                        }
                                    }
                                } else {
                                    label103: {
                                        var5 = 1;
                                        //以链表的方式插入
                                        ConcurrentHashMap.Node var13;
                                        Object var14;
                                        for(var13 = var7; var13.hash != var4 || (var14 = var13.key) != var1 && (var14 == null || !var1.equals(var14)); ++var5) {
                                            ConcurrentHashMap.Node var15 = var13;
                                            if ((var13 = var13.next) == null) {
                                                var15.next = new ConcurrentHashMap.Node(var4, var1, var2, (ConcurrentHashMap.Node)null);
                                                break label103;
                                            }
                                        }

                                        var11 = var13.val;
                                        if (!var3) {
                                            var13.val = var2;
                                        }
                                    }
                                }
                            }
                        }

                        if (var5 != 0) {
						//添加节点完成后,如果节点的链表数据大于8,则需要转换成红黑树
                            if (var5 >= 8) {
                                this.treeifyBin(var6, var9);
                            }

                            if (var11 != null) {
                                return var11;
                            }
                            break;
                        }
                    }
                }
            }

            this.addCount(1L, var5);
            return null;
        } else {
            throw new NullPointerException();
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值