VarHandle原子更新:compareAndExchange与weakCompareAndSet

梦强小哥_3131

梦强小哥_3131

2026-05-15

1001人浏览

原创

compareAndExchange 总返回当前值(无论是否成功),适用于需旧值做分支判断的场景;weakCompareAndSet 仅返回布尔结果,可能假失败且无happens-before保证,适合可重试的轻量自旋操作。

varhandle原子更新:compareandexchange与weakcompareandset

VarHandle 的 compareAndExchange 和 weakCompareAndSet 都是原子读-改-写操作,但语义、用途和内存行为差异明显。选错可能引发逻辑错误或性能浪费,关键不在“哪个更强”,而在于“哪个更匹配你的场景”。

compareAndExchange:要旧值,也要确定性

它总是返回变量的**当前值**(无论是否成功交换),相当于一次原子的“读取 + 条件写入”。这个返回值就是你操作前的真实快照。

  • 适合需要基于旧值做后续判断的逻辑,比如限流器中检查当前请求数、状态机中验证前一状态是否为“INIT”再允许跃迁
  • 避免了先 get() 再 compareAndSet() 带来的两次 volatile 读开销,也消除了中间被其他线程修改导致的“值已变但没察觉”的竞态
  • 类型安全:返回值与字段声明类型严格一致,不发生 Integer/int 隐式装箱拆箱,没有 Atomic 类里常见的对象引用比较陷阱
  • 内存语义可选:有 compareAndExchange(默认)、compareAndExchangeAcquire、compareAndExchangeRelease 等变体,按需控制屏障强度

weakCompareAndSet:重试友好,但不保序

它只返回 boolean,表示“是否成功更新”。但它可能“假失败”——值没变,也返回 false;也不提供 happens-before 保证,即不确保对其他线程的可见顺序。

  • 底层通常映射为单条 CPU 指令(如 x86 的 cmpxchg),无额外内存屏障,高频自旋场景下比 compareAndSet 更轻量
  • 只适用于能容忍假失败、且逻辑天然支持重试的场合,比如无锁栈/队列的 push/pop 循环
  • 不能用于跨线程状态同步的关键路径:比如一个线程设了“RUNNING”状态,另一个线程靠 weakCompareAndSet 判断并执行动作,可能因缺少 happens-before 而看不到该状态变更
  • 注意命名误导:像 weakCompareAndSetVolatile 或 weakCompareAndSetAcquire 这类带修饰的方法,才提供对应语义的内存效果;裸名的 weakCompareAndSet 是 plain 语义,最弱

怎么选:看你要响应什么

不是性能优先,而是语义对齐。

  • 你需要“这次更新前它到底是什么?”→ 用 compareAndExchange
  • 你在写一个自旋重试循环,且失败后直接重来即可→ weakCompareAndSet 更高效
  • 你要确保状态变更对其他线程立即可见(比如从 STARTING → RUNNING)→ 必须用 compareAndSet 或带 acquire/release 的 compareAndExchange 变体
  • 你在替换 Unsafe 字段操作,且希望 JVM 直接生成最优指令→ VarHandle 是标准路径,但必须通过 MethodHandles.lookup() 正确构造,不能静态缓存通用 handle

常见误区提醒

别把 weakCompareAndSet 当成“慢一点的 compareAndSet”。它本质是不同契约:一个是“尽力尝试,失败不解释”,一个是“强一致性,失败必有因”。JDK 9+ 中 VarHandle 的这些方法已通过 @HotSpotIntrinsicCandidate 由 JVM 内联为原生指令,性能差距更多来自语义开销,而非实现缺陷。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11797

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8882

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7632

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1244

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

1008

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1496

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

3089

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20351

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1355

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习