CAS(Compare And Swap)机制在并发编程中是一个非常重要的概念,主要用于实现原子性操作,避免使用传统的锁机制,从而提高性能。
CAS 的基本原理
CAS 的核心思想是通过比较当前值与预期值来决定是否执行修改。其流程如下:
- 读取当前值:获取共享变量的当前值。
- 比较:将当前值与预期值进行比较。
- 交换:如果相等,则将共享变量更新为新值;如果不等,则不做任何修改。
这个过程是原子的,意味着在执行期间不会被其他线程中断。
CAS 的优点和缺点
-
优点:
- 无锁:通过无锁机制避免了传统锁带来的性能损耗。
- 高并发:支持多个线程同时进行操作,减少了上下文切换的开销。
-
缺点:
- ABA 问题:如果某个线程读取了值 A,然后另一个线程将 A 改为 B 再改回 A,CAS 操作会误以为值没有变化,导致潜在的问题。为了解决这个问题,可以使用版本号或其他标记。
- 性能瓶颈:在高竞争环境下,如果多个线程频繁失败,会导致性能下降。
代码示例
下面是一个使用 CAS 实现的示例:
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class CASExample {
private static final Unsafe unsafe;
private static final long stateOffset;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
stateOffset = unsafe.objectFieldOffset(CASExample.class.getDeclaredField("state"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private volatile int state = 0; // 共享变量
public void doSomething() {
int expectedValue = 0;
int newValue = 1;
// 使用 CAS 进行原子更新
while (!unsafe.compareAndSwapInt(this, stateOffset, expectedValue, newValue)) {
// 如果 CAS 失败,可能需要重新读取预期值
expectedValue = state; // 重新读取共享变量的当前值
}
}
}
应用场景
- 原子变量类:如
AtomicInteger
和AtomicLong
等,这些类在内部使用 CAS 来实现原子操作。 - 并发数据结构:如
ConcurrentHashMap
和ConcurrentLinkedQueue
,在这些数据结构中,CAS 用于确保线程安全的元素插入和删除。
总结
CAS 是一种高效的并发控制机制,适用于需要高并发而又不想使用传统锁的场景。通过理解 CAS 的原理和实现,可以帮助开发者在实际项目中选择合适的并发控制策略。
完整面试题库:
大厂经典面试题,30万字精心总结
⬇️⬇️⬇️
点击获取