CAS学习篇

1. 什么是CAS?

        只对一个变量,首先比较它的内存值与某个期望值是否相同,如果相同,就给它赋一个新值。原子操作。
 
2. JAVA中CAS实现
        JAVA中CAS是由UnSafe类提供。有3种见下图
 
 
       一看native方法就很明显,这是由虚拟机提供的实现。虚拟机源码就算了(能力有限),但是看方法入参: 对象实例、内存偏移量、字段期望值、字段新值。
很明显该方法是获取指定对象实例,根据相应偏移量找到字段,执行 CAS 操作。
 
3.CAS缺陷
  • 自旋 CAS 长时间地不成功,则会给 CPU 带来非常大的开销
  • 只能保证一个共享变量原子操作
  • ABA 问题

tips: ABA问题怎么解决呢

    1.ABA问题是什么意思?

           ABA问题就是如果有多个线程对一个原子类进行操作的时候,某个线程在短时间内将原子类的值A修改为B,又马上将其修改为A,之后其他线程还是会修改成功。

    考虑到文字太过惨白,上一个例子吧。。。

public static void main(String[] args) {

        AtomicInteger num = new AtomicInteger(1);

        Thread first = new Thread(() -> {
            System.out.println("first开始执行");
            int expect = num.get();
            System.out.println("first取得期望值" + expect);
            LockSupport.parkNanos(1000000000L);
            System.out.println("first-1 "+num.compareAndSet(expect, 4));

        });

        Thread second = new Thread(() -> {
            System.out.println("second开始执行");
            int expect = num.get();
            System.out.println("second取得期望值" + expect);
            System.out.println("second-1 "+num.compareAndSet(expect, 4));
            expect = num.get();
            System.out.println("second取得期望值" + expect);
            System.out.println("second-2 "+num.compareAndSet(expect, 1));
        });
        first.start();
        second.start();
    }
输出结果:

    first开始执行
            first取得期望值1
            second开始执行 
            second取得期望值1
            second-1 true
            second取得期望值4
            second-2 true
            first-1 true

    2.怎么解决?

           java中AtomicStampedReference<V>类,可以解决这种问题。原理就是增加一个版本号,每次改一次数据,版本号就会进行累加。

      

 

posted @ 2022-01-06 17:42  mfzcq  阅读(53)  评论(0)    收藏  举报