ConcurrentHashMap源码剖析03_addCount()方法详解

private final void addCount(long x, int check) {
				//as:cells
				//b:base
				//s:table
        CounterCell[] as; long b, s;
        //条件1:true表示as数组不为空,需要通过hash计算找到自己的cell
        //      false表示as数组为空,将当前数据累加到base
        //条件2:true表示cas失败,即发生冲突,所以需要创建cell数组
        // 		false表示cas成功,所以不需要创建cell数组
        if ((as = counterCells) != null ||
            !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
            //a:当前线程hash之后对应的cell
            //v:期望值
            //m:cell数组的长度
            CounterCell a; long v; int m;
            //true:表示未发生竞争
            boolean uncontended = true;
			
			//条件1:as == null || (m = as.length - 1) < 0 
			//true:说明线程是通过cas失败才进入的
			//条件2:a = as[ThreadLocalRandom.getProbe() & m]) == null 
			//true:当前cell是空的,需要线程来初始化
			//条件3:!(uncontended =U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
			//true:当前线程cas更新当前cell失败,需要进行重试
			
            if (as == null || (m = as.length - 1) < 0 ||
                (a = as[ThreadLocalRandom.getProbe() & m]) == null ||
                !(uncontended =
                  U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
                fullAddCount(x, uncontended);
                return;
            }
            if (check <= 1)
                return;
                //当前散列表的元素个数
            s = sumCount();
        }
        //表示一定是put来调用addcount
        if (check >= 0) {
        	//tab:table数组
        	//nt:nextTable
        	//n:table数组的长度
        	//sc:sizeCtl的临时值
            Node<K,V>[] tab, nt; int n, sc;
            
            //条件1:s >= (long)(sc = sizeCtl
            //表示sizeCtl是一个负数,正在扩容中
            //条件2:(tab = table) != null 恒成立
            //条件3:(n = tab.length) < MAXIMUM_CAPACITY,基本上也恒成立
            while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
                   (n = tab.length) < MAXIMUM_CAPACITY) {
                int rs = resizeStamp(n);
                //table正在扩容
                if (sc < 0) {
                    if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                        sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
                        transferIndex <= 0)
                        break;
                    if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
                        transfer(tab, nt);
                }
                else if (U.compareAndSwapInt(this, SIZECTL, sc,
                                             (rs << RESIZE_STAMP_SHIFT) + 2))
                    transfer(tab, null);
                s = sumCount();
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值