Java Monitor是synchronized的底层机制,每个对象隐式关联一个Monitor,其状态存储于对象头Mark Word中,包含Owner、EntryList和WaitSet三部分,支持重入与wait/notify协作。

Java 中的 Monitor(监视器)是 synchronized 关键字背后的底层机制,它确保同一时刻只有一个线程能执行被保护的代码块或方法。Monitor 不是 Java 语言层面的类,而是 JVM 规范定义的一种同步原语,由每个对象实例隐式关联一个 Monitor —— 也就是常说的“对象锁”或“内置锁”(intrinsic lock)。
Monitor 与对象头的关系
JVM 在对象内存布局中,将 Monitor 的状态信息(如持有线程、等待队列、计数器等)与对象头(Object Header)紧密绑定。具体来说:
- 对象刚创建时,其 Mark Word(标记字段)中记录的是无锁状态(如 hashcode 或偏向线程 ID);
- 当第一次有线程进入 synchronized 块时,JVM 尝试将该对象升级为轻量级锁,用 Mark Word 存储指向线程栈中 Lock Record 的指针;
- 若发生竞争(如另一个线程尝试获取同一把锁),则膨胀为重量级锁:Mark Word 指向一个操作系统互斥量(Mutex),而这个 Mutex 就对应着该对象的 Monitor 实例;
- Monitor 内部维护三个关键部分:Owner(当前持有锁的线程)、EntryList(等待获取锁的线程队列)、WaitSet(调用 wait() 后挂起的线程队列)。
Monitor 的典型工作流程
以 synchronized(obj) { ... } 为例,整个过程如下:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 线程 T1 执行到 synchronized 代码块入口,尝试获取 obj 的 Monitor;
- 若 Monitor 未被占用,T1 成功获取并成为 Owner,进入临界区;
- 若 T2 此时也来抢锁,发现 Owner 非空,则被加入 EntryList 并阻塞(park),等待被唤醒;
- T1 执行完 synchronized 块后释放 Monitor,JVM 从 EntryList 中随机唤醒一个线程(比如 T2),T2 尝试重新竞争锁;
- 若 T1 在临界区内调用了 obj.wait(),它会释放 Monitor 并进入 WaitSet,同时让出 CPU;其他线程调用 obj.notify() 或 notifyAll() 时,会将 WaitSet 中的线程移入 EntryList 等待重新竞争。
Monitor 和 wait/notify 的协作逻辑
wait()、notify()、notifyAll() 必须在 synchronized 块内调用,原因正在于它们操作的是同一个 Monitor:
立即学习“Java免费学习笔记(深入)”;
- wait():当前线程必须是 Monitor 的 Owner,否则抛出 IllegalMonitorStateException;成功后自动释放 Monitor,并把自己放入 WaitSet;
- notify():只唤醒 WaitSet 中的一个线程,将其移到 EntryList;但不立即交出 Monitor,被唤醒线程仍需等待当前线程退出 synchronized 块;
- notifyAll():将 WaitSet 全部移入 EntryList,所有线程重新竞争 Monitor;适合存在多个条件变量或避免信号丢失的场景。
Monitor 是可重入的
Java 的 Monitor 支持重入(Reentrant):同一线程可以多次获取同一把锁,每次 enter 都会增加锁计数器,每次 exit 减一,只有计数归零才真正释放 Monitor。这也是 synchronized 方法可以安全地调用本类其他 synchronized 方法的原因。

















