不推荐在生产代码中直接使用 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 <h3>替代方案:优先使用标准 API</h3>
- ✅ `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);
}
```
<p>不复杂但容易忽略:真正的高性能并发结构(如 Disruptor、Aeron)不是靠滥用 <code>Unsafe</code>,而是靠<strong>减少共享、避免伪共享、预分配内存、批处理</strong>等系统级设计。<code>Unsafe</code> 只是工具链中极小一环。</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











