CAS详解

目录

什么是CAS?

使用场景:分析在Java中如何利用CAS实现原子操作的

AtomicInteger的getAndAddInt方法:

Unsafe类:

缺点:


什么是CAS?

  • compare and swa:比较并交换,就是我认为V的值应该是A,如果是的话那我就把它改成B,如果不是A(说明被人修改过了),那我就不修改了,避免多人同时修改导致出错
  • CAS有三个操作数:内存值V,预期值A,要修改的值B,并且仅当预期值A和内存值V相同时,才将内存值修改为B,否则什么都不做,最后返回现在的V值
  • CPU特殊的指令:作为一条CPU指令,CAS指令本身是能够保证原子性的,不会有线程安全问题
/**
 * 描述:模拟CAS操作,等价代码
 */
class SimulatedCAS implements Runnable{
    private volatile int value;

    public synchronized int compareAndSwap(int expectedValue, int newValue) {
        int oldValue = value;
        if (oldValue == expectedValue) {
            value = newValue;
        }
        return oldValue;
    }


    @Override
    public void run() {
        compareAndSwap(0,1);
    }

    public static void main(String[] args) throws InterruptedException {
        SimulatedCAS r = new SimulatedCAS();
        r.value = 0;
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(r.value);
    }
}

执行结果: 1

使用场景:分析在Java中如何利用CAS实现原子操作的

  • AtomicInteger 加载Unsafe工具,用来直接操作内存数据
  • 用Unsafe来实现底层操作
  • 用volatile修饰value字段,保证可见性

AtomicInteger的getAndAddInt方法:

static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;



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;
    }

Unsafe类:

  • Unsafe 是CAS的核心类。Java无法直接访问底层操作系统,而是通过本地(native方法来访问),不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,提供了硬件级别的原子操作
  • valueOffset表示的是变量值在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的原值的,这样我们就可以通过unsafe来实现CAS了

缺点:

ABA问题:就是不知道中间有没有被修改过,有的场景修改过也无所谓,只要最后的值没有变化就可以,这是没问题的,如果一定要知道是否有修改过,一般的解决方法就是加个版本号

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值