★ synchronized 底层原理是什么?锁升级过程是怎样的?

结论先行:synchronized 基于**监视器锁(Monitor)**实现:字节码层面通过 monitorenter/monitorexit 进入与退出,锁状态记录在对象头的 Mark Word 中。JDK 6 引入偏向锁后,锁沿“无锁 → 偏向锁 → 轻量级锁 → 重量级锁”单向升级,只有竞争足够激烈才膨胀为依赖 OS 互斥量的重量级锁。

锁升级路线

锁状态触发条件竞争代价特点
无锁 / 偏向锁首次进入,记录线程 ID 到 Mark Word极低同一线程重复进入无 CAS
轻量级锁偏向失效、出现轻度竞争自旋 + CAS 抢锁,不阻塞
重量级锁自旋失败、竞争加剧线程阻塞挂起,交给 OS 调度

配套机制

  • Monitor 结构:每个 Java 对象关联一个 monitor;重量级锁时竞争线程进入 EntryList 排队,持锁者调用 wait 后进入 WaitSet。
  • 可重入:同一线程重复进入 synchronized 会累加计数器,逐次退出递减,归零才真正释放。
  • 不可中断:阻塞等待锁期间不能响应 interrupt,这是它和 Lock 的显著差异之一。
public class SyncDemo {
    private int count;

    public synchronized void incr() { // 修饰方法:锁对象是 this
        count++;
    }

    public void incrBlock() {
        synchronized (this) {         // 同步块:可缩小加锁范围
            count++;
        }
    }

    public static synchronized void stat() { // 静态方法:锁 Class 对象
        // 所有实例共享同一把类锁
    }
}

常见追问 / 记忆点

  • 记忆点:锁升级“偏向 → 轻量 → 重量”单向不可逆,竞争越激烈代价越高。
  • 追问:JDK 15 起默认禁用偏向锁,因为现代应用竞争普遍,偏向收益已经变小。
  • 追问:wait/notify 必须在 synchronized 块内调用,否则抛 IllegalMonitorStateException。
笔记加载中…