CAS 机制

CAS 是 Java 中 Unsafe 类里面的方法,它的全称是 CompareAndSwap,比较并交换的意思。它的主要功能是能够保证在多线程环境下,对于共享变量的修改的原子性。
举个例子,比如说有这样一个场景,有一个成员变量 state,默认值是 0,定义了一个方法 doSomething(),这个方法的逻辑是,判断 state 是否为 0 ,如果为0,就修改成 1。这个逻辑看起来没有任何问题,但是在多线程环境下,会存在原子性的问题,因为这里是一个典型的,Read - Write 的操作。一般情况下,我们会在 doSomething()这个方法上加同步锁来解决原子性问题。

java 复制代码
public class Example {
    private int state=0;
    public void doSomething(){
        if (state==0) { //多线程环境中,存在原子性问题
            state=1;
        }
    }
}

但是,加同步锁,会带来性能上的损耗,所以,对于这类场景,我们就可以使用 CAS机制来进行优化.这个是优化之后的代码如下,在 doSomething()方法中,我们调用了 unsafe 类中的compareAndSwapInt()方法来 达到同样的目的,这个方法有四个参数,分别是:当前对象实例、成员变量 state 在内存地址中的偏移量、预期值 0、期望更改之后的值 1。CAS机制会比较 state内存地址偏移量对应的值和传入的预期值 0 是否相等,如果相等,就直接修改内存地址中 state 的值为1.否则,返回 false,表示修改失败,而这个过程是原子的,不会存在线程安全问题。

java 复制代码
public class Example {
    private volatile int state=0;
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long stateOffset;
    static {
        try {
            stateOffset = unsafe.objectFieldOffset(Example.class.getDeclaredField("state"));
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }
    public void doSomething(){
        if (unsafe.compareAndSwapInt(this,stateOffset,0,1)) {
            // TODO
        }
    }
}

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

CAS 主要用在并发场景中,比较典型的使用场景有两个:

  • 第一个是 J.U.C 里面 Atomic 的原子实现,比如 AtomicInteger,AtomicLong。
  • 第二个是实现多线程对共享资源竞争的互斥性质,比如在 AQS、ConcurrentHashMap、ConcurrentLinkedQueue 等都有用到。
相关推荐
考虑考虑20 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613520 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊21 小时前
Java学习第22天 - 云原生与容器化
java
渣哥1 天前
原来 Java 里线程安全集合有这么多种
java
间彧1 天前
Spring Boot集成Spring Security完整指南
java
间彧1 天前
Spring Secutiy基本原理及工作流程
java
Java水解1 天前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆1 天前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学1 天前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole1 天前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端