CAS机制理解

CAS(CompareAndSwap)是Java中Unsafe类的一个方法,用于在多线程环境下保证对共享变量修改的原子性。它通过比较内存地址中的值与预期值,如果相等则原子性地更新值。CAS常用于并发编程,如Atomic类的实现以及在AQS、ConcurrentHashMap、ConcurrentLinkedQueue等并发容器中的应用。
摘要由CSDN通过智能技术生成

CAS是什么

CAS是Java中Unsafe类里面的方法,它的全称是CompareAndSwap,比较并交换的意思。它的主要功能是能够保证在多线程环境下,对于共享变量的修改的原子性,并不是CAS单点登录。

非CAS操作

举个例子,比如说有这样一个场景,有一个成员变量flag,默认值为0,等于0就修改成1。这个逻辑看起来没有任何问题,但是在多线程环境下,会存在原子性的问题,因为这里是一个典型的,Read-Write的操作。一般情况下,我们会在updateFlag()这个方法上加同步锁来解决原子性问题。

public class Demo {
    private int flag = 0;

    public void updateFlag() {
        //如果是0就改为1
        if (flag == 0) {
            flag = 1;
        }
    }
}

CAS操作

如果上面加同步锁,会带来性能上的损耗,所以,对于这类场景,我们就可以使用CAS机制来进行优化。
在 updateFlag()方法中,我们调用了 unsafe 类中的 compareAndSwapInt()方法来达到同样的目的。

import sun.misc.Unsafe;

public class Demo {
    private volatile int flag = 0;
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final Long flagValue;

    static {
        try {
            flagValue = unsafe.objectFieldOffset(Demo.class.getDeclaredField("flag"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void updateFlag() {

        /**
         * 第一个参数:当前对象实例
         * 第二个参数:成员变量 flag 在内存地址中的偏移量
         * 第三个参数:预期值 0
         * 第四个参数:期望更改之后的值 1
         */
        if (unsafe.compareAndSwapInt(this, flagValue, 0, 1)) {
            //todo
        }
    }
}

CAS 机制会比较 flag 内存地址偏移量对应的值和传入的预期值 0 是否相等,如果相等,就直接修改内存地址中 flag 的值为 1. 否则,返回 false,表示修改失败,而这个过程是原子的,不会存在线程安全问题。

CAS总结

CompareAndSwap 是一个 native 方法,实际上它最终还是会面临同样的问题,就是先从内存地址中读取 flag 的值,然后去比较,最后再修改。这个过程不管是在什么层面上实现,都会存在原子性问题。所以CompareAndSwap 的底层实现中,在多核 CPU 环境下,会增加一个Lock 指令对缓存或者总线加锁,从而保证比较并替换这两个指令的原子性。

CAS 主要用在并发场景中,比较典型的使用场景有两个。
第一个是 J.U.C 包里面 Atomic 的原子实现,比如 AtomicInteger、AtomicLong。
第 二 个 是 实 现 多 线 程 对 共 享 资 源 竞 争 的 互 斥 性 质 , 比 如 在 AQS 、ConcurrentHashMap、ConcurrentLinkedQueue 等都有用到。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值