答案是:自旋锁、适应性自旋和轻量级锁膨胀构成递进式优化链,自旋是竞争失败后的首道防线,适应性自旋智能调整自旋次数,自旋失效后触发轻量级锁向重量级锁的不可逆膨胀。

自旋锁、适应性自旋和轻量级锁膨胀,是 JVM 为减少线程阻塞开销而设计的一组递进式优化策略。它们不是并列关系,而是存在明确的触发顺序和逻辑依赖:自旋是轻量级锁竞争失败后的第一道防线;适应性自旋是对自旋行为的智能调整;而轻量级锁膨胀,则是在自旋失效后向重量级锁过渡的关键步骤。
自旋锁:忙等换上下文切换
当一个线程尝试获取已被占用的轻量级锁失败时,JVM 不会立刻挂起它,而是让它在用户态“原地空转”——反复检查锁是否释放(比如用 CAS 或读取对象头 Mark Word)。这种不放弃 CPU、只等一小会儿的做法,就是自旋锁。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 核心价值在于避免线程从用户态陷入内核态的代价:挂起/唤醒涉及操作系统调度,耗时远高于几轮循环
- 适用前提是锁持有时间极短(如几十纳秒到几微秒),比如简单计数器更新或字段赋值
- 默认最多自旋 10 次(可通过 -XX:PreBlockSpin 调整),超时即放弃自旋
适应性自旋:让自旋更“懂”这个锁
固定次数的自旋太机械——有些锁总是很快释放,有些却总要执行较重逻辑。适应性自旋让 JVM 记住历史:如果上次在同一把锁上自旋成功了,且持有线程当时仍在运行,就认为这次也大概率能成,于是延长自旋次数(比如升至 20 或 50 次);反之,若连续几次都自旋失败,下次可能直接跳过自旋,快速进入阻塞。
- 本质是基于锁使用模式的预测性优化,无需人工干预
- 从 JDK 6 起默认启用,由 JVM 自动管理,-XX:+UseSpinning 仅控制是否开启自旋机制本身
- 它不改变锁状态,只是优化“等待方式”,仍发生在轻量级锁阶段
轻量级锁膨胀:自旋失败后的必然升级
当自旋耗尽仍拿不到锁,说明竞争已超出轻量级锁的设计预期。此时 JVM 会将该锁“膨胀”为重量级锁:把锁记录(Lock Record)替换为指向操作系统互斥量(Mutex)的指针,后续所有竞争线程都会被挂起,进入阻塞队列等待唤醒。
- 膨胀不可逆:一旦升级为重量级锁,该对象后续加锁都走重量级路径,不再退回轻量级或偏向锁
- 膨胀时机严格限定在自旋结束之后,不是发生在获取轻量级锁时,而是在其竞争失败+自旋无效之后
- 注意:轻量级锁本身不是一种独立锁类型,而是“无锁→轻量级→重量级”膨胀链中的中间态,它的存在就是为了给自旋提供操作基础
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










