AtomicLong LongAdder 源码解析 Doug Lea太强了!!!

本文深入探讨了AtomicLong和LongAdder在Java并发编程中的应用。AtomicLong通过CAS实现原子性,但在高并发下可能导致CAS次数过多。LongAdder采用空间换时间策略,分散更新,降低冲突,提高性能。LongAdder的add方法和striped64类中的关键机制确保了其在并发场景下的优越性,但sum方法不保证实时性。总结来说,LongAdder在性能上优于AtomicLong,被推荐在高并发场景中使用。
摘要由CSDN通过智能技术生成

一 AtomicLong原理

AtomicLong通过cas+自旋更新AtomicLong中的value值,进而保证value的原子性,N个线程同时改变value的值,只能有一个线程更新成功,其他线程这次的cas是失败的
在这里插入图片描述
由于一次只能有一个线程修改成功,其他线程得要自旋,一直到修改失败,在并发量比较高的情况下,可能会导致这些线程占用长时间修改值失败,导致cas次数过多。

二 LongAdder原理

在高并发场景下LongAdder可以显著的提高性能。使用了空间换时间的思想,咋atomiclong中cas对一个value值的修改,使用了一个数组经行分散修改,这样cas修改失败的概率就会小许多。
例如有一个base值,有三个线程要对执行+1操作,这个时候只有一个线程能成功使用cas对base修改成功,其他线程都会转而去修改cell数组的值,例如cell[2],0,1位置都是0,这个时候要对

三 LongAdder源码

  • add方法 流程图
    在这里插入图片描述
    public void add(long x) {
   
       //  as表示cells的引用
       // b  表示获取的base的值
       // v 表示期望值
       // m为数组的长度
       // 表示当前线程路由命中的cell单元格
        Cell[] as; long b, v; int m; Cell a;
        //条件1:true 表示数组不为空 当前线程应该将数据写入到对应的cell中
                 false 表示数组未初始化为空,当前线程应该将数据写base中
        //条件2 :true 表示cas改变base失败 可能需要重试 或者 扩容
		
        if ((as = cells) != null || !casBase(b = base, b + x)) {
   
        //进入代码块的条件:
        1 数组已经出初始化了,当前线程应该将数据写入到对应的cell中
        2  数组为空,但是cas改变base出现了竞争
            boolean uncontended = true;

			 //条件1 2:判断数组是否为空,如果不是空,继续判断条件3
			 //条件3 :getProbe()获取当前线程的hash值(代名词以下都说是hash值),m表示cells长度-1,cells长度 一定是2的次方数,
			 true :表示当前线程经过路由后对应的数组的桶位为空,需要创建对象
			 false:说明当前线程对应的cell 不为空,说明 下一步想要将x值 添加到cell中。
			 //条件4: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)))
                //都有哪些情况会调用?
                //1 cells数组位空
                // 2 线程路由后对应下标的cells位空
                // 3  cas 修改cells对应的位置失败
                longAccumulate(x, null, uncontended);
        }
    }
  • striped64类中属性
当前机器cpu的数量,用来限定数组的大小
static final int NCPU = Runtime.getRuntime().availableProcessors();
用来减少cas替换次数的数组
 transient volatile Cell[] cells;
 没有发生过竞争时,数据会累加到 base上 | 当cells扩容时,需要将数据写到base中
 transient volatile 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值