juc组件以unsafe为底层执行引擎,其原子操作、线程挂起、锁机制等均直接依赖unsafe的native方法,如compareandswapint和park,绕过jvm抽象层直通硬件指令与os原语。
真相不在代码表面,而在juc组件运行时的行为逻辑里。unsafe不是被“大量依赖”——它是juc的底层执行引擎,没有它,atomicinteger不会原子、locksupport无法挂起线程、aqs根本建不起来。
看源码:从AtomicInteger的incrementAndGet切入
打开java.util.concurrent.atomic.AtomicInteger源码,它的incrementAndGet()方法最终调用的是:
unsafe.getAndAddInt(this, valueOffset, 1)
而getAndAddInt内部是一个典型的CAS自旋循环,核心是:
unsafe.compareAndSwapInt(this, valueOffset, expected, expected + 1)
这个compareAndSwapInt就是Unsafe提供的native方法——它直接映射到CPU的cmpxchg指令,绕过JVM字节码锁和内存模型抽象层。你看到的是Java方法,实际执行的是硬件级原子操作。
查字节码:验证Unsafe调用不可绕过
对任意一个使用ReentrantLock或ConcurrentHashMap的简单程序,用javap -c反编译其关键同步逻辑,会发现:
- 所有状态变更(如
state字段更新、Node链表插入)都伴随invokestatic sun/misc/Unsafe.*调用 - 没有一处用
synchronized或java.util.concurrent.locks.Lock实现底层状态变更——它们自己就构建在Unsafe之上
也就是说,高级锁只是Unsafe能力的封装,不是替代。
看JVM启动日志与模块约束
从JDK 9开始,sun.misc.Unsafe被移入jdk.unsupported模块。运行时加--add-exports java.base/jdk.internal.misc=ALL-UNNAMED才能反射获取实例,这本身就说明:
- JDK明确将Unsafe定位为“仅供内部使用”的基础设施
- JUC包(如
java.util.concurrent)被白名单授信,可直接调用;你的应用代码默认无权访问 - 这种模块隔离不是技术限制,而是设计宣言:Unsafe不是给你用的,是给JUC写的
跟踪线程调度:LockSupport.park()背后是什么
LockSupport.park()看起来是个普通工具方法,但点进去会看到:
- 它最终调用
unsafe.park(false, 0L) - 该方法触发JVM线程状态切换(从RUNNABLE → WAITING),并直接操作线程栈和系统级等待队列
- AQS中每个
acquire失败后的阻塞,本质都是Unsafe对OS线程原语的调用
所谓“并发控制”,在这里已脱离Java语言层,进入操作系统线程调度内核。
不复杂但容易忽略:JUC不是“用”了Unsafe,而是以Unsafe为地基重新定义了Java并发的执行语义。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











