当前位置: > 财经>正文

LongAdder源码原创+图解+视频讲解 如何进行黄金交易流程图解视频讲解大全

2023-08-12 15:50:08 互联网 未知 财经

LongAdder源码原创+图解+视频讲解

目录

AtomicLong用法

源码分析

问题

解决

LongAdder用法

高并发下效率测试

原理

源码

add(long x)

Striped64的longAccumulate  

伪共享

总结

视频讲解:

AtomicLong用法   public static void main(String[] args) {        AtomicLong i = new AtomicLong(0);​        System.out.println(i.getAndIncrement());        System.out.println(i.addAndGet(30));   } ​

源码分析

 

如果value被修改了, CAS失败, 那就获取最新值,继续CAS, 直到成功~

问题

如果并发特别大,修改频繁,那么你要CAS自旋很多次, 效率大大降低

AtomicLong 的 Add 操作是依赖自旋不断的 CAS 去累加一个 Long 值。如果在竞争激烈的情况下,CAS 操作不断的失败,就会有大量的线程不断的自旋尝试 CAS 会造成 CPU 的极大的消耗

解决

使用LongAdder

LongAdder用法

 

      LongAdder longAdder = new LongAdder();        longAdder.increment();        longAdder.add(10);        longAdder.sum();

高并发下效率测试 @Slf4jpublic class Demo12 {    public static void main(String[] args) throws Exception {            long start1 = System.currentTimeMillis();            testLongAdder();            System.out.println("LongAdder 耗时:" + (System.currentTimeMillis() - start1) + "ms");            long start2 = System.currentTimeMillis();            testAtomicLong();            System.out.println("AtomicLong 耗时:" + (System.currentTimeMillis() - start2) + "ms");            System.out.println("----------------------------------------");       }​​        static void testAtomicLong() throws Exception{            AtomicLong atomicLong = new AtomicLong();            List list = new ArrayList();            for (int i = 0; i < 9999; i++) {                list.add(new Thread(() -> {                    for(int j=0;j {                    for(int j=0;j 表示cells已经初始化过了,当前线程应该将数据写入到对应的cell中       // false-> 表示cells 未初始化,当前所有线程应该将数据写入base中​        //条件二:true-> 表示当前线程cas替换数据成功            //false-> 表示发生竞争了,可能需要重试 或者 扩容            //true 是指casBase(b = base, b + x),不是整体,是部分            //true时,取反是false        if ((as = cells) != null || !casBase(b = base, b + x)) {​            //true 未竞争     false 发生竞争            boolean uncontended = true;​           //条件一:true-> 说明 cells 未初始化,也就是多线程写base发生竞争           // false-> 说明 cells 已经初始化了,当前线程应该是 找自己的cell 写值            if (as == null || (m = as.length - 1) < 0 ||​                //条件二:getProbe() 获取当前线程的hash值, m表示 cells长度-1 cells长度 一定是2的次方数 16-1=15=1111 二进制                    // true-> 说明当前线程对应下标的cell 为空 ,需要创建longAccumulate 支持                    // false-> 说明当前线程对应的cell 不为空,说明 下一步想要将x值,添加到cell中               (a = as[getProbe() & m]) == null ||​                //条件三:整体而言,有取反,true-> uncontended为false cas操作失败,意味着当前线程对应的cell 有竞争               //false-> 表示cas成功                !(uncontended = a.cas(v = a.value, v + x)))​               //哪些情况会调用                    //true-> 说明 cells 未初始化,也就是多线程写base发生竞争                    //true-> 说明当前线程对应下标的cell 为空 ,需要创建longAccumulate 支持                    //true-> cas操作失败,意味着当前线程对应的cell 有竞争                longAccumulate(x, null, uncontended);       }   }}​

Striped64的longAccumulate  

    代码看不懂,请看我讲解的视频哈

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。