怎么用nanoTime与CAS构造高性能自适应自旋锁

夏婷酱_2476

夏婷酱_2476

2026-06-02

848人浏览

原创

system.nanotime() 不适合控制自旋——因其调用开销大(20–50 纳秒)、tsc 跨核不同步、引发缓存抖动;应改用尝试次数+历史成功率的自适应策略,配合极简 cas 循环与 thread.onspinwait()。

怎么用nanotime与cas构造高性能自适应自旋锁

不能用 System.nanoTime() 控制自旋过程——它本身开销不小,而且在不同 CPU 上 TSC(时间戳计数器)频率可能不一致,测出来的“纳秒耗时”不可靠,容易导致自旋策略失准。

为什么 nanoTime 不适合做自旋计时

自旋锁的核心诉求是:在极短时间内(比如几十到几百纳秒)判断是否该继续等待,还是该退让或挂起。而 System.nanoTime() 调用一次通常要 20–50 纳秒(取决于 JVM 和硬件),频繁调用反而掩盖了临界区的真实耗时,还引入额外分支和内存访问,破坏缓存局部性。

  • 每次调用都触发 JNI 进入本地方法,有固定开销
  • TSC 频率在多核/多 socket 系统中可能不同步,跨 CPU 读取的 nanoTime 值不可比
  • 高并发下大量线程同时调用,会加剧 cache line bouncing(缓存行抖动)

真正有效的自适应策略:基于尝试次数 + 历史成功率

JDK 的 synchronized 在轻量级锁阶段就采用类似思路:不看绝对时间,而看“最近几次自旋是否成功”。成功多就多旋几次,失败多就快速放弃。

Aibiye降AI率
Aibiye降AI率

Aibiye降AI率是一款AI工具,专注降低AIGC的AI写作助手,精准定位问题段落。

下载
  • 用一个 volatile 整型记录当前建议自旋次数(如初始为 10)
  • 每次 lock() 尝试前,按当前次数循环 CAS;若中途成功,记录“本次成功”,并小幅增加下次次数(如 +1)
  • 若全部失败,则大幅削减次数(如 ×0.7),并考虑调用 Thread.onSpinWait() 或 Thread.yield()
  • 可选:用 AtomicIntegerArray 按 CPU 核心号隔离计数,避免伪共享

CAS 自旋主体应极简,只做核心原子操作

自旋循环体内必须干净:仅含一次 CAS 尝试 + 极轻量控制逻辑。任何日志、计时、条件判断都会拖慢关键路径。

  • 推荐结构:while (!state.compareAndSet(0, 1)) { Thread.onSpinWait(); }
  • Thread.onSpinWait() 映射为 x86 的 PAUSE 指令,降低功耗、缓解流水线冲突,比空循环友好得多
  • 避免在循环里调用 System.nanoTime()、System.currentTimeMillis()、Thread.currentThread() 等非内联方法

需要超时或退让时,用 parkNanos 替代时间计算

如果确实要限制总等待时长(例如防止极端情况死等),应在自旋达到预设次数后,直接调用 LockSupport.parkNanos(timeoutNs),而不是自己累加 nanoTime。

  • parkNanos 是 JVM 优化过的原生挂起,底层由 OS 调度器保障精度,且不会干扰自旋主路径
  • timeoutNs 可设为固定值(如 1000 纳秒)或根据历史平均持有时间动态估算,但不要实时算
  • 注意:parkNanos 仍属阻塞操作,只应在自旋失效后启用,不是自旋的一部分

相关专题

更多
java
java

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

2023.06.15

10257

6

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

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

2023.07.05

7382

9

java自学难吗
java自学难吗

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

2023.07.31

6492

8

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

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

2023.08.01

1124

3

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

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

2023.08.02

928

3

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

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

2023.08.02

1356

5

java有什么用
java有什么用

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

2023.08.02

2709

5

java在线网站
java在线网站

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

2023.08.03

20011

3

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

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

2023.08.03

1195

8

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程