其他分享
首页 > 其他分享> > JUC高级多线程_12:CAS与ABA问题

JUC高级多线程_12:CAS与ABA问题

作者:互联网

我是 ABin-阿斌:写一生代码,创一世佳话。 如果小伙伴们觉得我的文章有点 feel ,那就点个赞再走哦。
在这里插入图片描述

文章目录

一、CAS简介

1. CAS有哪些操作:

2. 注意事项:

3. 代码演示:

/**
 * @description: Compare and swap 简称:CAS 中文:比较并交换
 */
public class CASDemo {
    public static void main(String[] args) {
        //原子类的类,主要用于在高并发环境下的高效程序处理,来帮助我们简化同步处理
        AtomicInteger atomicInteger = new AtomicInteger(2021);
        //比较并设置,参数一:期望值   参数二:更新值
        boolean update = atomicInteger.compareAndSet(2021, 2022);
        if (update) {
            System.out.println("修改成功:" + atomicInteger.get());
        } else {
            System.out.println("修改失败!:" + atomicInteger.get());
        }

        //以原子方式将当前值递增+1
        atomicInteger.getAndIncrement();
        boolean flag = atomicInteger.compareAndSet(2021, 2022);
        if (flag) {
            System.out.println("修改成功:" + atomicInteger.get());
        } else {
            System.out.println("修改失败!:" + atomicInteger.get());
        }
    }
}

运行结果:
在这里插入图片描述

AtomicInteger 类介绍:

AtomicInteger 源码解析:

在这里插入图片描述

getAndIncrement() 方法源码分析:

在这里插入图片描述

4. CAS的缺点

二、ABA问题

1. 什么是ABA

2. 代码演示

/**
 * @description: CAS:ABA问题测试
 */
public class ABADemo {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(96);
        // 如果我期望的值达到了,那么就更新,否则,就不更新
        System.out.println(atomicInteger.compareAndSet(96,100));
        System.out.println(atomicInteger.get());

        // ============== 捣乱的李四 ==================
        System.out.println(atomicInteger.compareAndSet(100,69));
        System.out.println(atomicInteger.get());

        // ============== 期望的结果 ==================
        System.out.println(atomicInteger.compareAndSet(69,100));
        System.out.println(atomicInteger.get());
    }
}

结果:

在这里插入图片描述

3. 如何避免ABA问题

注意:

代码演示:

/**
 * @description: 解决 CAS 带来的 ABA问题
 */
public class ABADemo2 {

    static AtomicStampedReference<Integer> atomic = new AtomicStampedReference<>(6, 1);

    public static void main(String[] args) {

        //使用版本号机制来验证ABA问题
        new Thread(() -> {
            //获取当前版本号
            int stamp = atomic.getStamp();
            System.out.println("线程A1的版本号为:" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            atomic.compareAndSet(6, 10, atomic.getStamp(), atomic.getStamp() + 1);
            System.out.println("线程A2的版本号为:" + atomic.getStamp());

            System.out.println(atomic.compareAndSet(10, 6, atomic.getStamp(), atomic.getStamp() + 1));
            System.out.println("线程A3的版本号为:" + atomic.getStamp());

        }, "线程A:").start();

        //使用【乐观锁】思想解决ABA问题
        new Thread(() -> {
            int stamp = atomic.getStamp();
            System.out.println("线程B1的版本号为:" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomic.compareAndSet(6, 2, stamp, stamp + 1));
            System.out.println("线程B2的版本号为:" + atomic.getStamp());

        }, "线程B:").start();
    }
}

结果展示:

在这里插入图片描述

标签:JUC,12,CAS,System,atomicInteger,atomic,println,多线程,out
来源: https://blog.csdn.net/Mango_Bin/article/details/118418321