不推荐在生产代码中直接使用 Unsafe 类进行 CAS 操作,因其绕过 Java 内存模型和安全检查,易引发并发 bug、JVM 崩溃及兼容性问题;Java 官方将其标记为 internal/unsupported,JDK 9 起强封装,JDK 17+ 默认禁止反射获取。

不推荐在生产代码中直接使用 Unsafe 类进行 CAS 操作。
它绕过 Java 内存模型和安全检查,极易引发不可预测的并发 bug、JVM 崩溃或跨版本兼容问题。Java 官方明确将其标记为 "internal" 和 "unsupported",自 JDK 9 起通过强封装限制访问,JDK 17+ 默认禁止反射获取 Unsafe 实例。
但如果你是在研究 JVM 底层、写高性能基础库(如 Netty、Aeron)、或做实验性性能调优,下面说明其原理与最小可行用法:
为什么 CAS 需要 Unsafe?
Java 的 `volatile` 只保证可见性和有序性,**不保证读-改-写操作的原子性**。比如 `i++` 是三步:读 i → 加 1 → 写回 i。多线程下可能丢失更新。 CAS(Compare-And-Swap)是 CPU 提供的原子指令(如 x86 的 `cmpxchg`),`Unsafe` 就是 JVM 暴露该能力的“后门”。获取 Unsafe 实例(仅限实验环境)
```java // ⚠️ JDK 9+ 需添加 --add-opens java.base/jdk.internal.misc=ALL-UNNAMED 启动参数 private static final Unsafe UNSAFE; static { try { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); UNSAFE = (Unsafe) f.get(null); } catch (Exception e) { throw new RuntimeException(e); } } ``` 注意:JDK 17+ 默认会抛 `InaccessibleObjectException`,必须配置 JVM 参数放开模块访问。对对象字段执行 CAS(最常用场景)
```java public class Counter { private volatile long value = 0; // 获取 value 字段在对象内存中的偏移量(编译期固定) private static final long VALUE_OFFSET; static { try { VALUE_OFFSET = UNSAFE.objectFieldOffset( Counter.class.getDeclaredField("value") ); } catch (Exception e) { throw new Error(e); } }public boolean compareAndSet(long expected, long newValue) {
return UNSAFE.compareAndSwapLong(this, VALUE_OFFSET, expected, newValue);
}
public long incrementAndGet() {
long current;
do {
current = value; // 先读 volatile 字段(保证最新值)
} while (!compareAndSet(current, current + 1)); // 失败则重试
return current + 1;
}}
关键点:
- `objectFieldOffset()` 必须在静态块中调用一次,开销大但只执行一次;
- `compareAndSwapLong()` 是硬件级原子指令,失败返回 `false`,需配合循环重试(即 CAS loop);
- `value` 仍需声明为 `volatile` —— 不是为了原子性,而是为了确保每次读取都从主存加载(避免线程缓存旧值导致无限重试)。
<H3>对数组元素执行 CAS(如实现无锁队列)</H3>
```java
private static final long ARRAY_BASE = UNSAFE.arrayBaseOffset(long[].class);
private static final int ARRAY_SCALE = UNSAFE.arrayIndexScale(long[].class);
// 计算索引 i 对应的内存地址:base + i * scale
long getAndAdd(long[] array, int i, long delta) {
long offset = ARRAY_BASE + ((long) i << getShift(ARRAY_SCALE));
while (true) {
long current = UNSAFE.getLongVolatile(array, offset);
long next = current + delta;
if (UNSAFE.compareAndSwapLong(array, offset, current, next)) {
return current;
}
}
}
// scale 是 2 的幂,用位移代替乘法更快
private static int getShift(int scale) {
return 31 - Integer.numberOfLeadingZeros(scale); // 如 scale=8 → shift=3
}替代方案:优先使用标准 API
- ✅ `java.util.concurrent.atomic` 包(`AtomicInteger`, `AtomicReference`, `VarHandle`)—— 底层就用 `Unsafe` 封装,但经过严格测试、适配各平台,并在 JDK 9+ 后逐步迁移到 `VarHandle`(更安全、标准化); - ✅ `VarHandle`(JDK 9+):官方支持的底层内存访问机制,语义清晰且受 JVM 保护: ```java private static final VarHandle VALUE_HANDLE = MethodHandles .lookup().findVarHandle(Counter.class, "value", long.class); public boolean compareAndSet(long expected, long newValue) { return VALUE_HANDLE.compareAndSet(this, expected, newValue); } ```不复杂但容易忽略:真正的高性能并发结构(如 Disruptor、Aeron)不是靠滥用 Unsafe,而是靠减少共享、避免伪共享、预分配内存、批处理等系统级设计。Unsafe 只是工具链中极小一环。


















