Java锁机制通过自旋锁与适应性自旋,以“忙等”换取调度开销降低;自旋锁在用户态循环检测锁释放,适用于极短持有时间场景;适应性自旋基于历史行为动态调整自旋次数,提升预测准确性,共同延缓锁膨胀。

Java 锁机制通过自旋锁与适应性自旋,核心是用“忙等”换“调度开销”,在锁持有时间短的场景下显著减少线程挂起/唤醒带来的上下文切换损耗。
自旋锁:避免内核态切换的第一步
当线程尝试获取一个已被占用的轻量级锁失败时,JVM 不会立刻让该线程进入阻塞状态,而是让它在用户态循环检查锁是否释放(例如反复读取对象头 Mark Word 或执行 CAS)。这种不交出 CPU、只等一小会儿的做法,就是自旋锁。
- 适用前提:锁被持有的时间极短(通常几十纳秒到几微秒),比如简单字段更新、计数器累加
- 默认最多自旋 10 次,可通过 -XX:PreBlockSpin 参数调整
- 优势在于完全避开操作系统调度——挂起和恢复线程需从用户态切入内核态,耗时远高于几轮空转
- 缺点也很直接:若锁迟迟不释放,CPU 就白白空转,变成资源浪费
适应性自旋:让等待更聪明
固定次数的自旋太死板。适应性自旋让 JVM 记住历史行为,动态决定本次该自旋多久:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 如果上次在同一把锁上自旋成功,且持有线程当时仍在运行,说明这把锁大概率很快释放,本次就延长自旋次数(比如升至 20 或 50 次)
- 如果连续几次都在这把锁上自旋失败,下次可能直接跳过自旋,快速进入阻塞
- 它不改变锁的状态,仍属于轻量级锁阶段的优化策略,从 JDK 6 起默认启用
- 本质是基于锁使用模式的预测性调优,无需人工干预,越用越准
它们如何协同提升效率
自旋锁和适应性自旋不是独立功能,而是轻量级锁竞争路径中的关键环节:
立即学习“Java免费学习笔记(深入)”;
- 轻量级锁本身提供了一个无重量的加锁基础,为自旋创造了条件
- 自旋锁是竞争失败后的首道防线,争取在毫秒级甚至微秒级内抢到锁
- 适应性自旋进一步压缩了“猜错”的概率,使自旋更精准、更省电
- 两者共同延缓了锁膨胀——只有自旋彻底失效后,才触发轻量级锁向重量级锁升级,避免过早陷入高成本的系统级阻塞

















