CAS

Nabila ·
更新时间:2024-09-20
· 557 次阅读

CAS是什么

CAS的全称为Compare-And-Swap,它是一条CPU并发原语
它的功能是判断内存某个位置的值是否为预期值,如果是则改为新的值,这个过程是原子的。

CAS并发原语体现在Java语言中就是sun.misc.Unsafe类中的各个方法。
调用Unsafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能。

由于CAS是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致问题。

比较当前工作内存中的值和主内存中的值,如果相同则执行规定操作,否则继续比较直到主内存和工做内存中的值一直(自旋)
CAS有三个操作数,内存值V,预期值A,要更新的值B,如果V==A,则V=B,否则什么都不做。

Java中对CAS的使用

JUC包-java.util.concurrent 中 AtomicInteger类
示例代码如下:

private static final Unsafe U = Unsafe.getUnsafe(); /** * 获取当前值并+1 * Atomically increments the current value, * with memory effects as specified by {@link VarHandle#getAndAdd}. * *

Equivalent to {@code getAndAdd(1)}. * * @return the previous value */ public final int getAndIncrement() { return U.getAndAddInt(this, VALUE, 1); } /** * Atomically adds the given value to the current value of a field * or array element within the given object {@code o} * at the given {@code offset}. * * @param o object/array to update the field/element in * @param offset field/element offset * @param delta the value to add * @return the previous value * @since 1.8 */ //o为当前对象,offset为内存地址偏移量,delta需要增加的值 @HotSpotIntrinsicCandidate public final int getAndAddInt(Object o, long offset, int delta) { int v; do { //获取当前对象在offset偏移量上的值 v = getIntVolatile(o, offset); } while ( !weakCompareAndSetInt(o, offset, v, v + delta)); return v; } @HotSpotIntrinsicCandidate public final boolean weakCompareAndSetInt(Object o, long offset,int expected, int x) { //如果当前对象,内存地址偏移量offset上的值为excepted, 则将该值替换为x return compareAndSetInt(o, offset, expected, x); } Unsafe底层源码

在这里插入图片描述

CAS缺点

1、循环时间长,系统开销大
do-while
2、只能保证一个共享变量的原子操作

3、CAS会产生ABA问题

ABA问题?

一个线程T1从内存位置V中取出值A,一个线程T2从内存位置V中取出值也是A,T1使用CAS算法 将A改为B,
然后又使用CAS算法将B改为A,然后T2使用CAS算法将A改为C
虽然T2操作成功,但并不代表整个过程是没有问题的。

如何解决ABA问题

1、修改版本号(时间戳)
示例:AtomicStampReference


作者:雪落南城



cas

需要 登录 后方可回复, 如果你还没有账号请 注册新账号