varhandle 是对 jmm 的精细化补充,通过标准化访问模式(如 getacquire/setrelease)提供比 volatile 更轻量、比 synchronized 更细粒度的内存序控制,并依托 jvm 层面的精准内存屏障实现跨平台一致语义。

VarHandle 是 Java 9 引入的轻量级、高性能的变量访问控制机制,它的底层直接依托 JVM 对内存访问语义的增强支持,而这一增强正是由 JSR 193(Variable Handles) 规范推动实现的。它不是对 JMM 的推翻或替代,而是对原有 Java 内存模型(JMM)在原子操作与内存序控制层面的重要补充和精细化提升。
VarHandle 如何补强 JMM 的能力边界
JMM 原本通过 synchronized 和 volatile 提供了较粗粒度的可见性与有序性保证,但存在明显局限:
-
volatile只能用于字段,无法作用于数组元素、堆外内存或动态计算出的地址位置; -
synchronized开销大,且不支持细粒度的内存序控制(如只想要 store-load 顺序,不需要互斥); - 旧有的
Unsafe虽灵活但被标记为内部 API,无正式语义保证,不同 JVM 实现行为可能不一致。
JSR 193 正是为解决这些问题而生:它将内存访问操作抽象为统一的 VarHandle 实例,并定义了一套标准化的访问模式(access modes),例如:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
-
get()/set()—— 普通读写(对应普通变量语义); -
getVolatile()/setVolatile()—— 等价于 volatile 字段访问; -
getAcquire()/setRelease()—— 提供 acquire-release 内存序,比 volatile 更轻量; -
compareAndSet()/weakCompareAndSet()—— 支持无锁编程所需的原子条件更新。
与 JSR 133 的承继关系:从“保障正确性”到“支持高效控制”
JSR 133(2004 年)奠定了现代 JMM 的基础,明确了 happens-before、volatile 重排序限制、final 字段初始化安全等核心语义。而 JSR 193(2017 年随 Java 9 发布)是在 JSR 133 构建的语义地基之上,进一步向 JVM 层面注入更精细的内存屏障指令能力:
- JVM 需为每种 VarHandle 访问模式生成对应强度的内存屏障(如 LoadLoad、StoreStore、LoadStore 等),这些屏障由 JIT 编译器根据目标 CPU 架构(x86/ARM/RISC-V)精准映射;
- 不再依赖
volatile字段的“全屏障”开销,比如setRelease在 x86 上可编译为普通 store(无额外指令),而在 ARM 上则插入 dmb st,真正做到“按需施加”; - 所有 VarHandle 操作的语义均由 JVM 规范明确定义,确保跨实现(HotSpot、OpenJ9 等)行为一致,终结了
Unsafe的“黑盒”状态。
实际影响:让高性能并发原语真正落地
VarHandle 不仅是 API 层的封装,它使以下关键基础设施成为可能:
-
Java 9+ 的
ConcurrentHashMap、StampedLock、Phaser全部切换为基于 VarHandle 实现,减少锁竞争与内存屏障冗余; -
响应式流(Reactive Streams)与 LMAX Disruptor 类框架 可安全使用
getAcquire/setRelease实现无锁 RingBuffer 生产消费同步; - Project Panama(Foreign Function & Memory API) 依赖 VarHandle 访问堆外内存,同时获得 JMM 级别的可见性与重排序约束。
它把原本属于 JVM 内部专家才能驾驭的内存序控制,变成了开发者可理解、可组合、可验证的标准化工具。










