
概述
CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用的技术。在Java并发包中,很多类都使用了CAS技术。由于CAS在面试中经常被问到,本文将详细介绍CAS的原理。
案例
在介绍CAS之前,我们先看一个例子。
java
public class VolatileTest {
public static volatile int race = 0;
private static final int THREADS_COUNT = 20;
public static void increase() {
race++;
}
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[THREADS_COUNT];
for (int i = 0; i
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i
increase();
}
}
});
threads[i].start();
}
// 等待所有线程执行完毕
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(race);
}
为了解决这个问题,我们可以使用Java并发包中的原子操作类,例如 `AtomicInteger`。将 `race` 改为 `AtomicInteger` 类型,使用 `getAndIncrement()` 方法替代 `race++`,可以确保每次都能获得正确的结果。而这个 `getAndIncrement()` 方法底层就是使用了CAS操作。接下来我们详细介绍CAS。
CAS是什么?
源码分析
在Java源码中,`compareAndSwapInt`方法底层就是实现了CAS操作。该方法在Unsafe类中对应的具体实现如下。可以看到调用了`Atomic::cmpxchg`方法。接下来我们继续深入探讨该方法。在Linux和Windows系统上的实现有所不同。下面是Linux系统上的一种实现方式:在Windows系统上的一种实现方式会稍有不同,但核心思想是一样的。关于Intel处理器对lock前缀的说明如下:确保对内存的读-改-写操作原子执行等特性保证了CAS操作的原子性和内存屏障效果。因此CAS同时具有volatile读和volatile写的内存语义。关于CAS的缺点和ABA问题将在下文详细解释。总的来说CAS是一种高效的解决原子操作问题的技术但仍然存在一些挑战需要解决。
