CAS(Compare-And-Swap)

CAS 操作包含三个操作数:

  1. 内存位置(V):需要更新的变量。

  2. 期望值(A):认为变量当前的值。

  3. 新值(B):希望将变量更新为的值。

CAS 的操作逻辑是:

  1. 比较内存位置的值是否等于期望值(A)。

  2. 如果相等,则将内存位置的值更新为新值(B)。

  3. 如果不相等,则不做任何操作。

CAS 的操作是原子的,即在执行过程中不会被其他线程打断。

CAS 的伪代码

boolean compareAndSwap(int memory, int expected, int newValue) {
    if (memory == expected) {
        memory = newValue;
        return true;
    } else {
        return false;
    }
}
CAS 的应用示例
实现自旋锁
public final boolean compareAndSet(boolean expect, boolean update)
class SpinLock {
    private AtomicBoolean locked = new AtomicBoolean(false);
​
    public void lock() {
        while (!locked.compareAndSet(false, true)) {
            // 自旋等待
        }
    }
​
    public void unlock() {
        locked.set(false);
    }
}
实现计数器
class Counter {
    private AtomicInteger count = new AtomicInteger(0);
​
    public void increment() {
        int oldValue;
        int newValue;
        do {
            oldValue = count.get();
            newValue = oldValue + 1;
        } while (!count.compareAndSet(oldValue, newValue));
    }
​
    public int getCount() {
        return count.get();
    }
}

CAS 的优缺点
优点
  • 无锁:避免了线程阻塞和上下文切换的开销。

  • 高性能:在低竞争场景下,性能优于传统的锁机制。

  • 简单易用:提供了丰富的原子操作方法。

缺点
  • ABA 问题:CAS 操作无法感知到值从 A 变为 B 又变回 A 的情况。

  • 高竞争场景性能下降:在高竞争场景下,CAS 操作可能会频繁失败,导致性能下降。

  • 只能保证一个变量的原子性:CAS 操作只能保证一个变量的原子性,无法保证多个变量的原子性。


CAS 的 ABA 问题
ABA 问题的描述

ABA 问题是指:

  • 线程 1 读取变量的值为 A。

  • 线程 2 将变量的值从 A 改为 B,然后又改回 A。

  • 线程 1 执行 CAS 操作,发现变量的值仍然是 A,认为没有变化,但实际上变量的值已经被修改过。

ABA 问题的解决方法
  • 版本号:为变量添加一个版本号,每次修改变量时版本号加 1。

  • AtomicStampedReference:Java 提供了 AtomicStampedReference 类,通过版本号解决 ABA 问题。

示例:
AtomicStampedReference<Integer> atomicStampedRef = new AtomicStampedReference<>(100, 0);
​
int[] stampHolder = new int[1];
int value = atomicStampedRef.get(stampHolder); // value = 100, stampHolder[0] = 0
atomicStampedRef.compareAndSet(100, 200, 0, 1); // true,当前值变为 200,版本号变为 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值