1. 简介
在并发编程中,线程之间的同步与协作是关键问题之一。Java 提供了多种机制来解决这些问题,其中 synchronized
关键字背后的核心机制就是 Monitor(监视器)。本文将从概念、特性、Java 实现方式等多个角度深入解析 Monitor 机制,并结合实际代码示例帮助你更好地理解和使用。
2. 什么是 Monitor?
Monitor 是一种同步机制,它为线程提供两个核心能力:
✅ 互斥访问(Mutual Exclusion):确保同一时刻只有一个线程可以执行某个关键代码段
✅ 线程协作(Cooperation):允许线程等待某些条件成立后再继续执行,比如使用 wait()
和 notify()
Monitor 之所以被称为“监视器”,是因为它监视着多个线程对共享资源的访问。
Monitor 概念最早在 1970 年代初由 P.B. Hansen 在论文《Shared Classes》中提出,随后由 C.A.R. Hoare 在《Monitors – an Operating System Structuring Concept》中进一步完善,并提出了使用信号量(Semaphore)实现 Monitor 的模型。
3. Monitor 的核心特性
Monitor 在并发编程中提供了以下三个关键特性:
- 互斥执行:同一时间只允许一个线程进入临界区
- 条件等待:线程可以在 Monitor 中等待某个条件成立
- 通知机制:一个线程可以通知其他等待中的线程,条件已经满足
这些特性使得 Monitor 成为实现线程安全和协作的重要工具。
4. Java 中 Monitor 的实现原理
Java 使用 synchronized
关键字作为 Monitor 机制的语法糖。它用于标记临界区(Critical Section),即多个线程可能同时访问的代码区域。
你可以将 synchronized
用于:
- ✅ 方法级别(synchronized 方法)
- ✅ 代码块级别(synchronized 语句块)
4.1. 方法 vs 代码块同步
同步方式 | 优点 | 缺点 |
---|---|---|
方法同步 | 简单易用,推荐新手使用 | 粒度粗,可能影响性能 |
代码块同步 | 控制更精细,安全性更高 | 使用复杂,容易出错 |
从安全角度考虑,使用私有锁对象进行同步(如 private final Object lock = new Object();
)是更推荐的做法。
4.2. Monitor 的类比理解:建筑与房间模型
Java 的 Monitor 实现基于两个核心概念:
- Entry Set(入口集合)
- Wait Set(等待集合)
我们可以用“建筑与房间”的类比来理解 Monitor 的工作机制:
- 整个 Monitor 是一座建筑
- “临界资源”是里面的一个“专属房间”
- Entry Set 是“大厅”,线程在这里排队等待进入房间
- Wait Set 是“等候室”,线程在这里等待特定条件满足
- 线程就是想要进入房间的人
线程进入 Monitor 的过程如下:
- ✅ 进入建筑:尝试进入 Monitor(调用
synchronized
) - ✅ 进入专属房间:获取 Monitor 锁(进入临界区)
- ✅ 在房间内执行:持有 Monitor(执行临界代码)
- ✅ 离开房间:释放 Monitor 锁
- ✅ 离开建筑:退出 Monitor(退出同步块)
如果线程调用了 wait()
,它会释放 Monitor 并进入 Wait Set,直到其他线程调用 notify()
将其唤醒。
JVM 的线程调度器通常使用优先级调度算法,同优先级下使用 FIFO(先进先出)策略决定线程执行顺序。
5. wait() 与 notify() 方法详解
wait()
和 notify()
是 Monitor 机制中用于线程协作的关键方法,必须在 synchronized
块中使用。
✅ wait() 方法
synchronized (lock) {
while (!condition) {
lock.wait(); // 释放锁并进入等待状态
}
// 条件满足后继续执行
}
⚠️ 注意:wait()
会释放当前线程持有的 Monitor 锁,并进入 Wait Set,直到被其他线程唤醒。
✅ notify() 方法
synchronized (lock) {
condition = true;
lock.notify(); // 唤醒一个等待中的线程
}
notify()
会唤醒一个在 Wait Set 中等待的线程,但不会立即释放锁,唤醒的线程会在当前线程退出同步块后才重新竞争锁。
6. 小结
Monitor 是 Java 并发编程中的核心机制,隐藏在 synchronized
关键字的背后。它通过 Entry Set 和 Wait Set 实现了线程的互斥访问与协作等待。
本文我们从 Monitor 的定义、特性、Java 实现机制、线程协作方法等多个角度进行了详细解析,并通过“建筑与房间”的类比加深了理解。
✅ 掌握 Monitor 的工作原理,有助于你写出更高效、安全的并发代码。
作者邮箱: dev@example.com
参考资料: Shared Classes, Monitors – an Operating System Structuring Concept