自适应自旋是JVM根据锁的历史成功率、持有线程状态及系统负载动态调整轻量级锁自旋次数的机制,目标是在避免线程挂起开销与防止CPU空转间实现智能平衡;它自JDK 6起默认启用,按锁对象粒度维护统计,多核环境下生效,单核或长持有场景自动降级为阻塞。

自适应自旋不是固定次数的“死等”,而是 JVM 根据锁的历史表现动态调整等待策略,核心目标是:在锁持有时间短、竞争不激烈时,用 CPU 时间换线程切换开销;在锁长期被占或频繁失败时,及时退避,避免空转浪费。
为什么需要自适应?
早期自旋锁靠参数(如 -XX:PreBlockSpin)设固定次数,比如默认 10 次。但现实场景千差万别:
- 刚自旋到第 9 次,持有线程就释放了锁——少等一次就成功
- 锁实际要等 50ms,而自旋只持续 1ms 就放弃——后续仍得走挂起/唤醒流程,白耗一次切换
固定值无法适配不同锁的“脾气”,自适应机制就是让 JVM 学会“看情况办事”。
自适应怎么判断该多旋还是少旋?
关键依据是同一把锁近期的自旋成败记录:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 上次在该锁上自旋成功 → 认为这次大概率也成,下次自旋次数翻倍(上限受限)
- 上次自旋失败 → 推断锁持有时间偏长或竞争激烈,下次自旋次数减半(下限不低于 0)
- 不是全局统一调参,而是按锁对象粒度维护历史状态,不同对象互不影响
它在哪起作用?
自适应自旋主要嵌入在 synchronized 的锁升级路径中:
- 当轻量级锁竞争失败、准备升级为重量级锁前,JVM 会先尝试自旋
- 此时启用自适应逻辑,决定是否继续自旋、自旋多久
- 若自旋期间锁被释放,直接获取成功;超时则进入 Monitor 阻塞队列
它不单独存在,而是轻量级锁向重量级锁过渡时的“缓冲动作”。
有哪些实际约束?
自适应不是无条件优化,受硬件与场景限制:
- 只在多核 CPU 上生效——单核下自旋线程抢不到执行权,纯属浪费
- 仅适用于锁持有时间极短(微秒到毫秒级)的场景,否则自旋收益远低于成本
- JDK 6 起默认开启,JDK 7+ 后不再提供开关参数,完全由 JVM 自主决策

















