CAS 操作在 JDK 中是通过哪个类来实现的?
参考回答
在 JDK 中,CAS(Compare-And-Swap,比较并交换)操作是通过 Unsafe 类 来实现的。Unsafe 是一个 Java 内部类,提供了直接操作内存和执行底层操作的能力,它是 Java 中实现 CAS 操作的核心。
详细讲解与拓展
1. 什么是 CAS?
CAS 是一种无锁的原子操作机制,常用于实现并发编程中的原子性。它的核心逻辑是:
- 比较内存中的值与预期值。
- 如果相同,就更新为新值。
- 如果不同,则说明其他线程已经修改过该值,CAS 操作失败。
2. CAS 在 JDK 中的实现:Unsafe 类
Unsafe 类简介
Unsafe 是 sun.misc 包下的一个类,提供了一些用于内存操作和底层系统交互的方法。CAS 操作是通过 Unsafe 提供的以下方法实现的:
compareAndSwapInt(Object obj, long offset, int expected, int newValue):比较并交换整数值。compareAndSwapLong(Object obj, long offset, long expected, long newValue):比较并交换长整型值。compareAndSwapObject(Object obj, long offset, Object expected, Object newValue):比较并交换对象引用。
源码示例:Unsafe 类的部分方法
以下是 compareAndSwapInt 的定义:
public final native boolean compareAndSwapInt(Object obj, long offset, int expected, int x);
obj:要操作的对象。offset:字段在对象中的内存偏移量。expected:期望值。x:要更新的新值。
3. CAS 操作在 JDK 中的应用
1. AtomicInteger 的实现
CAS 操作是 java.util.concurrent.atomic 包下类的核心,例如 AtomicInteger、AtomicLong 等。
AtomicInteger 源码片段:
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private volatile int value;
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
解释:
value是一个volatile变量,用于保证可见性。- 使用
Unsafe.compareAndSwapInt实现了原子更新。 valueOffset表示value在内存中的偏移量,Unsafe通过偏移量直接操作内存。
2. ReentrantLock 的实现
CAS 操作也被用于实现 ReentrantLock 的公平锁和非公平锁的锁竞争逻辑。
源码片段:
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
4. CAS 的优点与缺点
优点
- 无锁机制:避免了传统锁机制的阻塞问题,提高了并发性能。
- 高效:适合高并发场景,特别是对原子操作的需求。
缺点
- ABA 问题
: 如果某个值在中间被其他线程改为另一个值再改回来,CAS 无法检测到。
- 解决方案:引入版本号(如
AtomicStampedReference)。
-
自旋开销: CAS 操作可能需要反复重试,消耗 CPU 资源。
-
只能保证一个变量的原子性: 对于多个变量的原子操作,需要配合其他机制。
5. 小结
- CAS 操作在 JDK 中通过
Unsafe类实现,并用于java.util.concurrent.atomic和ReentrantLock等核心并发工具中。 Unsafe提供了底层的compareAndSwapXXX方法,直接操作内存,实现高效的原子性操作。- 虽然 CAS 提高了并发性能,但也有局限性(如 ABA 问题),需要根据具体场景选择合适的并发控制方案。