(九)聊一下并发中的自增原子操作的AtomicLong在JDK1.8之后是如何优化成LongAdder的,为什么要优化自增原子类?

(一)先聊聊AtomicLong的基本概念,然后聊一下他的缺陷问题,然后引出LongAdder的优点

(1)大家都使用过AtomicInteger、AtomicLong等这几类原子性的工具类,具体怎么用我就不说了,就说一下他们的大概的基本实现原理
在这里插入图片描述

  • 其实这些基本的原子操作的思想大体都是,
	expect 表示当前内存中你所预期望的值,update 是你想要更新的值
    public final boolean compareAndSet(long expect, long update) {
    	这个this表示了当前对象的地址,后面的valueOffset是在该对象开始的位置加上这个valueOffset的偏移量,就能拿到的是当前对象的值
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }

  • 然后这里又会去调用unsafe对象的native方法,这个是基于C写的代码
把上面的compareAndSwapLong的入参和这个对应起来,然后其实就是判断当前位置的值,是不是和你预期的expect的值相等,如果相等就把valueOffset处的值更新为update你想要更新的结果,
如果失败的话,就不做改变(说明这个值跟你期望的不一致,就意味着这个值被别的线程修改过了,就什么也不操作)
public final native boolean compareAndSwapLong(Object var1, 
											long var2,  
											long var4, 
											long var6);

(2)这样带来的缺点就是,如果有大量的线程进行CAS的时候,那么就会导致大量的线程都在进行CAS,但是能够成功的又很少,那么就会出现有大量线程进行自旋,并且对CPU造成大量的资源消耗的缺点,所以这个时候就进行了优化,那么就出现了LongAdder

  • 但是如果要是在并发度不是很高的情况下,其实使用LongAdder和AtomicLong的差别不大
  • 尽量减少热点冲突,不到最后万不得已,尽量将CAS操作延迟

(二)先说一下LongAdder的整体设计思想

(1)其实整体的设计思想就是:如果在如果有很多个线程来进行CAS的时候,而在LongAdder中他其实是借鉴的了HashMap1.7的思想,他把这个资源进行分段来进行维护,他内部维护了一个Cell[]数组,每个Cell对象中就包含了资源的值,其实就是和HashMap中的那个table数组,table数组中放的都是包含key-value的一个Node对象

(2)然后在竞争激烈的时候就直接怼base值进行增加,但是如果当线程竞争足够激烈的时候就会统计每个线程对应的Cell[这个是每个线程的hash出来的一个下标值]进行相加

value=base+∑i=0nCell[i]

在这里插入图片描述
(3)主要的Add方法
在这里插入图片描述
(4)如果
在这里插入图片描述
参考:https://segmentfault.com/a/1190000015865714#articleHeader4

(三)在详细的看LongAdder的具体是如何实现的?

(四)总结一下自己的感悟和理解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值