2 CAS是什么

CAS是什么?

CAS的全称为Compare-And-Swap,它是一条CPU并发原语

它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子性的

CAS并发原语体现在JAVA语言中就是sum.misc.Unsafe类中的各个方法,调用UnSafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令。这是一个完全依赖于硬件的功能,通过它实现了原子操作。再次强调,由于CAS是一种系统原语,原语数语操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行的过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致问题。

Unsafe类

是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据。Unsafe类存在sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作的执行依赖于Unsafe类的方法

注意Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用系统底层资源执行相应任务。

//比较与交换:如果期望值与物理内存值一致,交换成功。 
//参数 当前对象 内存偏移量 期望值 更新值
public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
  } 

public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
           // 获取最新值
            var5 = this.getIntVolatile(var1, var2);
          // 比较并交换 直到交换成功 
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); 

        return var5;
    }

CAS缺点

  1. 循环时间长CPU开销大

  2. 只能保证一个共享变量的原子操作

  3. 引出来的ABA问题

CAS算法是实现一个重要前提需要取出`内存中某个时刻的数据并在当下时刻比较并替换,那么在这个时间差会导致数据的变化。

比如说一个线程one从内存位置V取出A,这时候另一个线程two也从内存中取出A,并且线程two进行了一些操作将值变成了B,然后线程two又将V位置的数据变成A,这时候one进行CAS操作发现内存中仍然是A,然后线程one操作成功。

尽管线程one的CAS操作成功,但是不代表这个过程就是没有问题的。

CAS解决ABA问题


public class CASDemo {

    static AtomicReference<Integer> atomicReference = new AtomicReference<>(1);
    static AtomicStampedReference<Integer> stampedReference = 
      new AtomicStampedReference<>(1,1);

    public static void main(String[] args) throws InterruptedException {
         // 复现ABA问题
        new Thread(()->{
            atomicReference.compareAndSet(1,100);
            atomicReference.compareAndSet(100,1);
            System.out.println(atomicReference.get());
        },"t1").start();

        new Thread(()->{
            try { Thread.sleep(1000); } catch (InterruptedException e) { }
            atomicReference.compareAndSet(1,101);
            System.out.println(atomicReference.get());
        },"t2").start();

        Thread.sleep(2000);
        System.out.println("++++++++++++解决ABA问题+++++++++++++");
      
       //  解决ABA问题 添加版本号
        new Thread(()->{
            stampedReference.compareAndSet(1,stampedReference.getReference()+1,1,stampedReference.getStamp()+1);
            stampedReference.compareAndSet(1,stampedReference.getReference()+1,2,stampedReference.getStamp()+1);
            System.out.println(stampedReference.getReference());
        },"t3").start();
        new Thread(()->{
            try { Thread.sleep(3000); } catch (InterruptedException e) { }
            boolean b = stampedReference.compareAndSet(1, stampedReference.getReference() + 1, 2, stampedReference.getStamp() + 1);
            System.out.println(b+"-----"+stampedReference.getReference());
        },"t4").start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值