首页 > 其他 > 详细

深入理解CAS

时间:2021-05-05 18:01:46      阅读:23      评论:0      收藏:0      [点我收藏+]

深入理解CAS

  • 什么是 CAS

    大厂你必须要深入研究底层!有所突破!

    public class Test01 {
        // CAS  compareAndSet : 比较并交换!
        public static void main(String[] args) {
            AtomicInteger atomicInteger = new AtomicInteger(2021);
            // 期望、更新
            // public final boolean compareAndSet(int expect, int update)
            // 如果我期望的值达到了,那么就更新,否则,就不更新, CAS 是CPU的并发原语!
            System.out.println(atomicInteger.compareAndSet(2021, 2022));
            System.out.println(atomicInteger.get());
    
            System.out.println(atomicInteger.compareAndSet(2021, 2022));
            System.out.println(atomicInteger.get());
        }
    }
    
  • Unsafe 类

    技术分享图片技术分享图片

技术分享图片
CAS : 比较当前工作内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就 一直循环!

缺点:
1、 循环会耗时
2、一次性只能保证一个共享变量的原子性
3、ABA问题

  • CAS : ABA 问题(狸猫换太子)

    技术分享图片
    public class Test01 {
        // CAS  compareAndSet : 比较并交换!
        public static void main(String[] args) {
            AtomicInteger atomicInteger = new AtomicInteger(2021);
            // 期望、更新
            // public final boolean compareAndSet(int expect, int update)
            // 如果我期望的值达到了,那么就更新,否则,就不更新, CAS 是CPU的并发原语!
    
            // ============== 捣乱的线程 ==================
            System.out.println(atomicInteger.compareAndSet(2021, 2022));
            System.out.println(atomicInteger.get());
    
            System.out.println(atomicInteger.compareAndSet(2022, 2021));
            System.out.println(atomicInteger.get());
            // ============== 期望的线程 ==================
            System.out.println(atomicInteger.compareAndSet(2021, 2022));
            System.out.println(atomicInteger.get());
        }
    }
    

解决方法:引入原子引用!

public class Test01 {
    // AtomicStampedReference 如果泛型是包装类,注意对象的引用问题
    // 正常业务引用的是对象
    public static void main(String[] args) {
        AtomicStampedReference<Integer> integerAtomicStampedReference = new AtomicStampedReference<>(11,1);
        new Thread(()->{
            int stamp = integerAtomicStampedReference.getStamp();//获取版本号
            System.out.println("版本号a1:"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //版本号+1
            System.out.println(integerAtomicStampedReference.compareAndSet(11, 12,
                    integerAtomicStampedReference.getStamp(), integerAtomicStampedReference.getStamp() + 1));
            System.out.println("版本号a2:"+integerAtomicStampedReference.getStamp());

            //版本号+1
            System.out.println(integerAtomicStampedReference.compareAndSet(12, 11,
                    integerAtomicStampedReference.getStamp(), integerAtomicStampedReference.getStamp() + 1));
            System.out.println("版本号a3:"+integerAtomicStampedReference.getStamp());
        },"a").start();

        new Thread(()->{
            int stamp = integerAtomicStampedReference.getStamp();//获取版本号
            System.out.println("版本号b1:"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //版本号+1
            System.out.println(integerAtomicStampedReference.compareAndSet(11, 22,
                    integerAtomicStampedReference.getStamp(), integerAtomicStampedReference.getStamp() + 1));
            System.out.println("版本号b2:"+integerAtomicStampedReference.getStamp());
        },"b").start();
    }
}

深入理解CAS

原文:https://www.cnblogs.com/saxonsong/p/14731467.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!