varhandle 通过 getandbitwiseor、getandbitwiseand、getandbitwisexor 等内置方法支持整数类型的原子位操作,底层映射为 lock-prefixed cpu 指令,无需自旋,性能高效;使用时需确保类型匹配与正确访问模式。

VarHandle 本身不直接提供位操作(如 or、and、xor)的原子方法,但可以通过 getAndBitwiseOr、getAndBitwiseAnd、getAndBitwiseXor 等内置方法,配合 compareAndSet 或循环重试策略,安全高效地实现原子位更新。
支持的原生原子位操作方法
Java 9+ 的 VarHandle 已为整数类型(int、long、byte 等)预置了三类原子位运算方法:
- getAndBitwiseOr:读取当前值,再按位或指定掩码,返回旧值(原子)
- getAndBitwiseAnd:读取当前值,再按位与指定掩码,返回旧值(原子)
- getAndBitwiseXor:读取当前值,再按位异或指定掩码,返回旧值(原子)
这些方法底层通常编译为 CPU 的 lock-prefixed 指令(如 lock orl),无需自旋或 CAS 循环,在 x86 上性能接近直接内存操作。使用前需确保 VarHandle 类型匹配且访问模式正确(如使用 VarHandle::ofField 获取字段句柄时,字段必须是 volatile 或 final+static)。
设置/清除单个标志位的推荐写法
对布尔型标志位(如第 n 位),应避免手动构造掩码 + CAS 自旋。优先使用内置位操作:
- 设定位(bit n):
handle.getAndBitwiseOr(obj, 1L - 清除位(bit n):
handle.getAndBitwiseAnd(obj, ~(1L - 翻转位(bit n):
handle.getAndBitwiseXor(obj, 1L
注意:若操作 long 字段,掩码用 1L;操作 int 字段则用 1 并确保 VarHandle 类型为 int,否则可能触发非法参数异常。
复合位操作与条件更新
当需“仅在某几位为 0 时才设置”等条件逻辑,VarHandle 不提供内置支持,此时应组合 get + compareAndSet 实现无锁循环:
- 先读取当前值
current = handle.get(obj) - 计算目标值(如:仅当 bit3=0 时设置 bit2 →
target = current | mask2 & ~(mask3)) - 用
handle.compareAndSet(obj, current, target)尝试提交;失败则重试
该模式适用于细粒度状态机(如多标志协同控制),但要注意避免 ABA 问题——若业务语义要求严格顺序,可考虑升级为 AtomicStampedReference 或引入版本号字段。
跨平台与内存模型注意事项
VarHandle 的位操作遵循 Java 内存模型(JMM)的 volatile 语义:每次调用都具备获取(acquire)和释放(release)效果,能防止指令重排序,并保证修改对其他线程可见。但在弱一致性架构(如 ARM/PowerPC)上,其性能优势更显著——因为 JVM 会自动插入必要屏障,开发者无需手动添加 Unsafe.fullFence()。
另外,不支持浮点字段或对象引用类型的位操作;尝试对 double 字段调用 getAndBitwiseOr 会抛出 UnsupportedOperationException。










