当前位置: 首页 > 后端技术 > Java

AtomicXXX效果很好,为什么阿里推荐使用LongAdder呢?面试必问,..

时间:2023-04-01 17:50:27 Java

采访连环炮先来一系列简单的采访,看看你能顶得住几轮?栈长:1、在多线程的情况下,进行数字累加(count++)需要注意什么?张三:注意在累加方法上加同步锁,否则会出现变量可见性问题,变量值会被其他线程覆盖,出现不一致。张三:volatile可以保证可见性,但是不能保证原子性和线程安全。Stacklength:3除了加同步锁,还有别的办法吗?张三:在JDK中也可以使用原子类,比如:AtomicInteger和AtomicLong,就是用CAS算法实现的乐观锁。堆长:4。是的,你还知道什么吗?张三:呃……说真的,你能顶得住多少发?这些问题是Java程序员面试过程中必须要问的。出镜率极高,Java程序员必懂。这些问题在Java面试库小程序中也有详细的解答,这里就不展开了。你还知道什么吗?最后一轮答题就是今天的话题!更好的选择:LongAdder您还在使用AtomicInteger和AtomicLong原子类进行并发累加操作吗?那你就OUT了!除了AtomicInteger和AtomicLong,其实在JDK8中推荐使用LongAdder进行原子操作,性能更好。如果你还在用JDK7-,那我没说。即便如此,你也不能找借口不知道,毕竟现在JDK8已经是主流应用版本了。阿里巴巴最新Java开发手册定义如下:这份完整的阿里巴巴Java开发手册,您可以关注公众号:Java核心技术,回复:手册,即可下载完整高清版。如果你还没有使用过LongAdder,不妨看看这篇文章来刷新一下知识,栈长带你涨知识!为什么想出LongAdder?我们都知道在JDK5中已经创建了AtomicInteger、AtomicLong等原子类,这也是JDK8之前常用的原子操作类。我们来看一下AtomicLong的累积源码:大家都知道这些原子类是全部通过CAS算法。实现的乐观锁不断地比较旧值和已有值,直到比较成功后才修改成功,结束循环。这样一来,就会出现问题。如果并发数高,会造成过多不必要的“循环”,势必会影响CPU的性能。因此,JDK8又创建了一个LongAdder,也是在atomic包下:可以看到同一个包下还有一个LongAccumulator类。本文就不展开了,stackmanager下次再开详细分析,关注公众号:Java技术栈,我写完第一时间推送。为什么LongAdder性能更好?下面分析一下LongAdder类的源码:LongAdder中维护了一个Cell数组。当Cell不为空时,size为2的次方的大小。每个Cell数组都有一个long变量,初值为0。使用来存储每个Cell的值:然后使用sum方法求和Cell数组然后返回基值:关于基值:LongAdder一开始并不会创建Cell数组,它自己会维护一个基值,只有在CAS更新失败时才会创建或扩容。再来看看AtomicXXX和LongAdder的更新对比图:Cell数组相当于一个分段的概念。AtomicXXX中的一个值被分成多个值进行管理。当CAS更新失败时,不会重试当前循环,而是尝试获取Other资源锁,减少了AtomicXXX对单个资源的竞争,因此LongAdder的性能更高。LongAdder虽然性能更好,但是有什么缺点吗?LongAdder带来好的性能,肯定是有代价的。既然维护了Cell数组,就意味着占用了更多的内存空间,以空间换时间是值得的。实战测试既然官方说在高并发的情况下性能更好,那么是这样吗?stackmanager一定要实战一下,打消大家的疑惑!AtomicLong测试代码:/***@author:stacklength*@from:公众号Java技术栈*/privatestaticvoidatomicLongTest()throwsInterruptedException{longstart=System.currentTimeMillis();ExecutorServicees=Executors.newFixedThreadPool(MAX_POOL_SIZE);对于(inti=0;i{for(intj=0;j{for(intj=0;j