Java CAS 与 Unsafe 深度解析

Java CAS 与 Unsafe 深度解析

如果说 AQS 是并发框架的"内核设计",那么 CAS 和 Unsafe 就是"CPU 级指令暴露层"。

几乎所有 Java 并发能力,最终都会落到这两个关键词上。


一、为什么 Java 需要 CAS?

在并发世界里,我们要解决的核心问题只有一个:

多个线程同时修改同一份数据,如何保证正确性和性能?

传统方案:锁(Lock / synchronized)

  • 优点:语义简单、安全

  • 缺点:

    • 线程阻塞 / 唤醒
    • 上下文切换
    • 可扩展性差

👉 在 高并发、短临界区 场景下,锁的代价非常高。


二、CAS 是什么?(Compare And Swap)

1️⃣ CAS 的定义

CAS 是一种乐观并发控制原语,由 CPU 原子指令支持。

它的语义是:

复制代码
if (memory == expected)
    memory = newValue
else
    fail

2️⃣ CAS 的三个操作数

参数 含义
V 内存位置(地址)
A 期望值(Expected)
B 新值(Update)

👉 这是一个不可分割的原子操作


三、CAS 在 Java 中的体现

AtomicInteger 示例

java 复制代码
AtomicInteger i = new AtomicInteger(0);

i.incrementAndGet();

底层等价逻辑:

java 复制代码
do {
    int old = value;
} while (!CAS(value, old, old + 1));

👉 失败就重试,自旋直到成功


四、CAS 的三大问题(面试高频)

1️⃣ ABA 问题

复制代码
A → B → A

CAS 只关心"当前值是否等于期望值",不关心"中间发生了什么"。

解决方案
  • AtomicStampedReference
  • AtomicMarkableReference

2️⃣ 自旋开销

  • 并发度高
  • CAS 长时间失败

👉 会 白白消耗 CPU

解决思路:

  • 限制自旋次数
  • 结合 park/unpark

3️⃣ 只能保证单变量原子性

CAS 只能操作一个内存地址。

👉 多变量一致性仍然需要锁。


五、Unsafe 是什么?

1️⃣ Unsafe 的定位

java 复制代码
sun.misc.Unsafe

Unsafe 是 JVM 提供的"后门 API",允许 Java 直接操作内存和线程。

⚠️ 名字就说明了一切:

用不好 = JVM 崩溃


2️⃣ 为什么 Unsafe 不对普通开发者开放?

  • 绕过 Java 内存安全检查
  • 绕过对象生命周期管理
  • 绕过访问控制

👉 这是 JVM 实现者 / 并发框架作者的工具


六、Unsafe 提供了哪些核心能力?

1️⃣ CAS 原子操作(最重要)

java 复制代码
compareAndSwapInt
compareAndSwapLong
compareAndSwapObject

AQS、AtomicXXX、FutureTask 全靠它。


2️⃣ 内存操作(堆外内存)

java 复制代码
allocateMemory
freeMemory
getLong
putLong

👉 Netty / DirectBuffer 的基础。


3️⃣ 内存屏障(Memory Fence)

java 复制代码
loadFence()
storeFence()
fullFence()

👉 用于实现 Java 内存模型(JMM)。


4️⃣ 线程控制

java 复制代码
park()
unpark()

👉 AQS / FutureTask 阻塞机制的底层。


5️⃣ 对象实例化(绕过构造器)

java 复制代码
allocateInstance(Class)

👉 反序列化框架的关键能力。


七、CAS + Unsafe 如何支撑整个 JUC?

复制代码
AtomicXXX        → Unsafe.CAS
AQS              → Unsafe.CAS + park/unpark
ReentrantLock    → AQS
FutureTask       → Unsafe.CAS
ThreadPool       → ctl CAS

👉 JUC ≈ Unsafe 的工程化封装


八、Unsafe 与 Java 内存模型(JMM)的关系

Unsafe 的 CAS 本身:

  • 是原子操作
  • 隐含内存屏障

保证:

  • 写入对其他线程可见
  • 禁止指令重排

👉 这是 volatile + CAS 能成立的根本原因


九、为什么 JDK 9 之后要"封禁" Unsafe?

问题:

  • 滥用 Unsafe
  • 不可维护
  • 不可移植

解决方案:

能力 官方替代
CAS VarHandle
堆外内存 ByteBuffer / Panama
原子类 AtomicXXX

👉 从"黑魔法"走向"标准能力"


十、Unsafe vs VarHandle(趋势)

对比点 Unsafe VarHandle
安全性
API 稳定性
可读性
推荐程度

十一、工程实践建议(专家经验)

✅ 你应该直接使用:

  • AtomicXXX
  • Lock / AQS
  • ConcurrentXXX

❌ 不建议:

  • 业务代码直接使用 Unsafe
  • 手写 CAS 算法

👉 Unsafe 是"造轮子者"的工具,不是"用轮子者"的工具


CAS 是并发世界的最小原子操作,Unsafe 是 JVM 向上暴露这些原子能力的接口;整个 Java 并发体系,本质上都是对 CAS + Unsafe 的层层封装与约束。


相关推荐
Javatutouhouduan12 小时前
2026Java面试的正确打开方式!
java·高并发·java面试·java面试题·后端开发·java编程·java八股文
chao18984413 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
JAVA面经实录91713 小时前
Java初级最终完整版学习路线图
java·spring·eclipse·maven
赏金术士13 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
Cat_Rocky14 小时前
k8s-持久化存储,粗浅学习
java·学习·kubernetes
楼兰公子14 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
知识领航员14 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
吴声子夜歌14 小时前
Go——并发编程
开发语言·后端·golang
释怀°Believe14 小时前
Spring解析
java·后端·spring
ooseabiscuit15 小时前
Laravel4.x:现代PHP框架的奠基之作
java·开发语言·php