CAS学习笔记
CAS
-
全称Compare-And-Swap,它是一条CPU并发原语
-
它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的
- CAS并发原语体现在JAVA语言中就是sun.misc.Unsafe类中的各个方法。调用Unsafe类中CAS方法,JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能,通过它实现了原子操作。
-
由于CAS是一种系统原语。原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成数据不一致的问题。
import java.util.concurrent.atomic.AtomicInteger; public class CASDemo { public static void main(String[] args){ AtomicInteger atomicInteger = new AtomicInteger(5); System.out.println(atomicInteger.compareAndSet(5, 2019)+"\t current data:"+atomicInteger.get()); System.out.println(atomicInteger.compareAndSet(5, 209)+"\t current data:"+atomicInteger.get()); } }
底层原理
-
atomicInteger.getAndAddInt
-
Unsafe
-
Unsafe是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定的内存数据。
-
Unsafe类中的方法都是native方法,它们使用JNI的方式访问本地C++实现库
-
Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作执行依赖于Unsafe类的方法
-
valueOffset,表示该变量值在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的
-
- var1:AtomicInteger对象本身 - var2 = valueOffset 内存偏移量 - var5为当前对象的值(get)[类似从主内存中得到值拷贝在自己的工作内存中] - 当前对象![](https://img2022.cnblogs.com/blog/2182638/202202/2182638-20220220154217495-1926170565.png)
-
去比较,若相同加var4
- ![](https://img2022.cnblogs.com/blog/2182638/202202/2182638-20220220154226137-130907120.png)
CAS缺点
- synchronized 一致性保证,并发性下降
- 循环时间长开销大
- 只能保证一个共享变量的原子操作
- ABA问题