synchronized 锁的释放机制

synchronized 锁的释放机制是通过 JVM 底层的 Monitor 锁模型计数器机制 实现的。以下是具体的释放逻辑和触发条件:


一、锁释放的触发条件

  1. 正常执行结束
    当线程执行完 synchronized 修饰的代码块或方法时,JVM 会自动调用 monitorexit 指令释放锁。
    同步代码块:通过 monitorentermonitorexit 指令显式控制锁的获取与释放。
    同步方法:通过 ACC_SYNCHRONIZED 标志隐式触发锁的获取和释放,方法结束时自动释放锁。

  2. 异常退出
    如果在 synchronized 代码块或方法中抛出未捕获的异常,JVM 会执行 monitorexit 指令释放锁。
    • 编译时会为同步代码块生成两个 monitorexit 指令:一个用于正常退出,另一个用于异常路径。

  3. 显式调用 wait()
    线程在 synchronized 代码块内调用 wait() 方法时,会暂时释放锁并进入等待状态,直到其他线程调用 notify()/notifyAll() 唤醒它。


二、锁释放的核心机制

  1. 计数器递减
    • 每个对象关联一个 Monitor 锁,内部维护一个计数器(_count)。
    • 线程每次进入 synchronized 代码块时计数器加 1,退出时减 1。
    • 当计数器归零时,锁完全释放,其他线程可竞争获取。

  2. Monitor 对象的状态管理
    持有锁的线程(_owner:释放锁后,_owner 置为 null,计数器归零。
    等待队列(_EntryList_WaitSet:锁释放后,JVM 会从 _EntryList_WaitSet 中唤醒线程重新竞争锁。


三、不同场景的锁释放示例

1. 同步代码块
public void method() {
    synchronized (this) {
        // 代码逻辑
    } // 此处自动执行 monitorexit 释放锁
}

• 无论正常结束还是抛出异常,monitorexit 都会触发锁释放。

2. 同步方法
public synchronized void method() {
    // 代码逻辑
} // 方法结束自动释放锁

• 通过 ACC_SYNCHRONIZED 标志隐式管理锁,无需显式字节码指令。

3. 异常场景
public void method() {
    synchronized (this) {
        throw new RuntimeException(); // 触发异常,自动释放锁
    }
}

• 即使未捕获异常,JVM 也会执行 monitorexit 指令释放锁。


四、锁释放的底层实现(字节码层面)

  1. 同步代码块
    编译后生成 monitorenter 和两个 monitorexit(正常退出和异常退出)指令:

    public void method();
      Code:
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter     // 获取锁
         4: ...              // 业务代码
        13: monitorexit      // 正常退出释放锁
        14: goto 20
        17: aload_1
        18: monitorexit      // 异常退出释放锁
        19: athrow
        20: return
    
  2. 同步方法
    方法访问标志包含 ACC_SYNCHRONIZED,JVM 在方法入口和出口隐式管理锁。


五、注意事项

  1. 不会释放锁的操作
    Thread.sleep()Thread.yield() 不会释放锁。
    • 线程挂起(如 suspend())也不会释放锁。

  2. 可重入性
    • 同一线程可多次获取锁(计数器递增),需对应次数的退出操作才能完全释放。


总结

synchronized 锁的释放依赖于 JVM 的 Monitor 模型和计数器机制,通过以下方式触发:

  1. 代码块或方法正常结束。
  2. 未捕获异常抛出。
  3. 显式调用 wait()
    其底层通过 monitorexit 指令或隐式标志确保锁的正确释放,保障线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

堕落年代

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值