深度解析 synchronized 锁升级:无锁→偏向锁→轻量级锁→重量级锁的触发条件

深度解析 synchronized 锁升级机制

Java 中的 synchronized 锁升级是 JVM 优化同步性能的核心机制,其状态转换路径如下:

graph LR
A[无锁] --> B[偏向锁]
B --> C[轻量级锁]
C --> D[重量级锁]

1. 无锁 → 偏向锁
  • 触发条件
    当线程首次访问同步块时,JVM 检测到无竞争环境(即未发生过锁争用)。
  • 核心机制
    通过 CAS 操作将锁对象的 Mark Word 中的线程 ID 设置为当前线程 ID,并置标志位为 101(偏向模式)。
  • 优势
    后续该线程进入同步块时无需 CAS 操作,直接检查线程 ID 匹配即可。
  • 数学描述
    设 $T_{id}$ 为线程 ID,$M$ 为 Mark Word,偏向锁建立过程可表示为:
    $$ M_{\text{新}} = \text{CAS}(M_{\text{旧}}, \text{NULL}, T_{id}) \oplus \text{偏向模式位} $$
2. 偏向锁 → 轻量级锁
  • 触发条件
    第二个线程尝试获取锁时(发生轻度竞争),JVM 在全局安全点撤销偏向锁。
  • 核心机制
    1. 暂停持有偏向锁的线程
    2. 检查原线程状态:
      • 若已退出同步块 → 直接转无锁状态
      • 若仍在同步块中 → 升级为轻量级锁
    3. 将 Mark Word 复制到线程栈帧(Lock Record),并用 CAS 替换为指向 Lock Record 的指针(标志位 00)。
  • 数学描述
    设 $P_{\text{LR}}$ 为 Lock Record 指针,升级过程为:
    $$ M_{\text{新}} = \text{CAS}(M_{\text{旧}}, M_{\text{原值}}, P_{\text{LR}}) $$
3. 轻量级锁 → 重量级锁
  • 触发条件
    满足以下任一条件:
    • 线程自旋超过阈值(默认 10 次)
    • 等待线程数 > CPU 核心数
    • 调用 wait() 等阻塞方法
  • 核心机制
    1. JVM 创建重量级锁的监视器(Monitor)
    2. 将 Mark Word 替换为指向 Monitor 的指针(标志位 10
    3. 竞争线程进入阻塞队列,由操作系统调度
  • 性能影响
    线程切换成本从纳秒级升至微秒级,满足关系:
    $$ \text{切换开销}{\text{重量级}} \approx 100 \times \text{切换开销}{\text{轻量级}} $$
关键参数与优化
  • 偏向锁延迟
    默认开启延迟(-XX:BiasedLockingStartupDelay=4000ms),避免启动阶段的竞争误判。
  • 降级机制
    重量级锁不会主动降级,仅当对象无任何线程引用时回归无锁状态。
  • 锁消除场景
    若 JIT 编译器通过逃逸分析确认无竞争,会直接跳过锁升级流程。

通过此机制,JVM 实现了从低竞争(偏向锁)到高竞争(重量级锁)的自适应优化,平衡了同步性能与资源开销。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值