跳到主要内容

Compare and Sweep

比较并替换。

CAS 是一种乐观锁,它的基本思想是:先读取内存中的值,然后进行比较,如果内存中的值和期望值相等,就将新值写入内存,否则不断重试。

volatile 只能保证可见性,无法保证原子性。

CAS 的实现

CAS: Compare and swap , 比较并交换。是一种无锁非阻塞算法的实现。

CAS 有三个操作数

  • V:需要读写的内存值
  • A:旧的预期值
  • B:要修改的更新值。

当前仅当 V == A 时,CAS 通过原子方式用新值 B 来更新 V 的值,否则不会执行任何操作。

CAS 实现的原理

CAS 是通过 JNI 来调用 CPU 的原子指令(cmpxchg 指令)来实现的。

CAS 的缺陷

- **ABA 问题**
- 描述:原来是 A ,被线程 1 修改成了 B,然后又被线程 2 修改成了 A。CAS 无法感知到这种变化。
- 解决方案:增加一个版本号,每次修改都会增加版本号,这样就可以避免 ABA 问题。 1A -> 2B -> 3A
- **循环时间开销大**
- 描述:修改失败时,会一直自旋,直到成功为止,这样会导致 CPU 开销大。
- **只能保证一个共享变量的原子操作**
- 描述:无法同时使 i 和 j 加1
- 解决方案:将 i、j 合并成一个对象,然后对这个对象进行 CAS 操作。

什么时候使用 CAS ? 什么时候使用 synchronized ?

竞争较少的时候使用 CAS,竞争多的情况下使用 synchronized。