Java并发编程——CAS

一、CAS原理

什么是CAS?
compare and swap,比较并交换。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。

//CAS:compareAndSwap:比较并交换
public class CASDemo {

    public static void main(String[] args) {
        AtomicInteger atomicInteger=new AtomicInteger(2020);
        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());

        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());
    }
}

Java并发编程——CAS_第1张图片
通过查看源码,发现AtomicInteger底层是通过调用Unsafe中的方法来实现的
Java并发编程——CAS_第2张图片
Unsafe中的方法通过native调用底层C++或通过自旋锁的方式操作内存
Java并发编程——CAS_第3张图片

二、ABA问题

Java并发编程——CAS_第4张图片
原子引用解决ABA问题

public class CASDemo {
    public static void main(String[] args) {
        AtomicStampedReference<Integer> atomicStampedReference=new AtomicStampedReference<>(1,1);//初始值,版本号

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();//获得版本号
            System.out.println("A1->" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(atomicStampedReference.compareAndSet(1, 2, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
            System.out.println("A2->" + atomicStampedReference.getStamp());
            System.out.println(atomicStampedReference.compareAndSet(2, 1, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
            System.out.println("A3->" + atomicStampedReference.getStamp());
        },"A").start();

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();//获得版本号
            System.out.println("B1->" + stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(atomicStampedReference.compareAndSet(1, 6, stamp, stamp + 1));
            System.out.println("B2->" + atomicStampedReference.getStamp());
        },"B").start();
    }
}

Java并发编程——CAS_第5张图片

你可能感兴趣的:(Java并发编程(补充),java,并发编程,多线程)