LongAdder 源码

LongAdder

LongAdder。 有两个, 一个base, 一个cell 数组, 如果当前线程不存在竞争,都是线性的,那么就会一直累加到base里面, 如果存在竞争, 就会分发给cell 数组,,最后cell 数组求和+ base 就是最终的结果。
AtomicLong 则是通过不停的cas 去尝试改变,LongAdder 采用的是以空间换时间的方式

 public void add(long x) {
 		
        Cell[] as; long b, v; int m; Cell a;
        // 条件-: true: 如果cells数组不为空, 需要初始化cells数组
        //        false  如果cells数组为空
        // 条件二: true: 进行cas 失败 ,需要扩容 或者 重试
        //。       false。cas成功
        //  如果当前不存在线程竞争关系,那么对于base 的cas 操作一定会成功, 如果失败,就代表失败,就需要进行cells数组初始化
        if ((as = cells) != null || !casBase(b = base, b + x)) {
        	//。如何进入? 
        	//。当存在竞争关系的时候, cas 操作失败, 需要cells 数组进行初始化 , 会进入
            //  uncontended. 为true 代表不存在竞争 
            boolean uncontended = true;
            //。条件-: true: as 为null, 没有被初始化。  原因: 防止多线程情况下,有线程已经进行初始化了,但是其他线程哪里的as还是null
            //。       false: as 被初始化
            // 条件二: getProbe(). 计算hash值
            //。   	   true: hash值 & m  =。分配的数组下标,  如果为null ,代表该位置没有累加运算过, 就需要new Cell 
            //。   	   false: 不为null, 已经做过了
            //。条件三: true: cas 操作失败
            //。		false: cas 操作成功
            if (as == null || (m = as.length - 1) < 0 ||
                (a = as[getProbe() & m]) == null ||
                !(uncontended = a.cas(v = a.value, v + x)))
                //。进入的三种情况, cells 没有进行初始化,
                //				  下标对应位置没有被使用过, 需要new 一个Cell 对象
                //				  cas 操作失败
                longAccumulate(x, null, uncontended);
        }
    }
//。x。 要累加的值
//。wasUncontended。 是否cas 操作失败过
final void longAccumulate(long x, LongBinaryOperator fn,
                              boolean wasUncontended) {
                              
        // hash 值                   
        int h;
        //。如果没有进行分配
        if ((h = getProbe()) == 0) {
        	// 初始化
            ThreadLocalRandom.current(); // force initialization
            //。分配hash值
            h = getProbe();
            // 默认分配到0下标,也就是没有发生冲突
            wasUncontended = true;
        }
        //。代表该下标是否发生冲突
        boolean collide = false;                // True if last slot nonempty
        //。自旋
        for (;;) {
            Cell[] as; Cell a; int n; long v;
            //。条件:	true: cells 被初始化了, 将对应数据写入cells 中
            if ((as = cells) != null && (n = as.length) > 0) {
            	//。如果当前分配下标为 null, 说明需要new 一个Cell 对象
                if ((a = as[(n - 1) & h]) == null) {
                	//。当前锁是否被占用, 0 为没有被占用
                    if (cellsBusy == 0) {       // Try to attach new Cell
                        Cell r = new Cell(x);   // Optimistically create
                        //。 尝试获取锁, 获取到了锁
                        if (cellsBusy == 0 && casCellsBusy()) {
                            boolean created = false;
                            try {               // Recheck under lock
                                Cell[] rs; int m, j;
                                // 条件一: cells 没有被其他线程改变
                                // 条件二: 分配的下标没有被使用
                                if ((rs = cells) != null &&
                                    (m = rs.length) > 0 &&
                                    rs[j = (m - 1) & h] == null) {
                                    rs[j] = r;
                                    created = true;
                                }
                            } finally {
                                cellsBusy = 0;
                            }
                            if (created)
                                break;
                            continue;           // Slot is now non-empty
                        }
                    }
                    collide = false;
                }
                // 条件: true: 发生冲突,cas 失败
                //		false: 没有发生过冲突
                else if (!wasUncontended)       // CAS already known to fail
                    wasUncontended = true;      // Continue after rehash
                //。条件: true: 进行cas 操作 成功, 就break
                // 		 false: 进行cas 失败
                else if (a.cas(v = a.value, ((fn == null) ? v + x :
                                             fn.applyAsLong(v, x))))
                    break;
                //。如果当前cells 数组长度 大于CPU数量,或者 cells 已经被其他线程扩容,或者正在扩容
                else if (n >= NCPU || cells != as)
                	//。扩容标记为false
                    collide = false;            // At max size or stale
                //。扩容标记为 true
                else if (!collide)
                    collide = true;
                //。如果当前线程获取到锁
                else if (cellsBusy == 0 && casCellsBusy()) {
                    try {
                        //。判断cells 有没有被操作过
                        if (cells == as) {      // Expand table unless stale
                        	// 进行扩容, 扩大2倍
                            Cell[] rs = new Cell[n << 1];
                            for (int i = 0; i < n; ++i)
                                rs[i] = as[i];
                            cells = rs;
                        }
                    } finally {
                        cellsBusy = 0;
                    }
                    collide = false;
                    continue;                   // Retry with expanded table
                }
                h = advanceProbe(h);
            }
            //。如果线程获取到锁, 并且cells 数组没有被扩容
            else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
                boolean init = false;
                try {                           // Initialize table
                    //。如果没有其他线程改变, 就进行初始化
                    if (cells == as) {
                        Cell[] rs = new Cell[2];
                        rs[h & 1] = new Cell(x);
                        cells = rs;
                        init = true;
                    }
                } finally {
                    cellsBusy = 0;
                }
                if (init)
                    break;
            }
            //。 进行cas。操作, 尝试加载 base 上面
            else if (casBase(v = base, ((fn == null) ? v + x :
                                        fn.applyAsLong(v, x))))
                break;                          // Fall back on using base
        }
    }

你可能感兴趣的:(LongAdder 源码)