Java 线程间通信(wait / notify)
线程间通信是多线程编程中的重要概念。理解 wait/notify 机制是实现线程协调的基础。本章将详细介绍 Java 中的线程间通信。
wait/notify 机制
wait() 方法
wait() 使当前线程进入等待状态,直到其他线程调用 notify() 或 notifyAll()。
public final void wait() throws InterruptedException;
public final void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException;
重要规则:
- 必须在
synchronized代码块中调用 - 调用
wait()会释放锁 - 被唤醒后需要重新获取锁
synchronized (lock) {
while (condition) {
lock.wait(); // 释放锁,进入等待
}
// 被唤醒后,重新获取锁,继续执行
}
notify() 方法
notify() 唤醒一个等待该对象锁的线程。
public final void notify();
特点:
- 必须在
synchronized代码块中调用 - 随机唤醒一个等待的线程
- 不释放锁,需要执行完同步块才释放
synchronized (lock) {
// 修改条件
condition = true;
lock.notify(); // 唤醒一个等待的线程
}
notifyAll() 方法
notifyAll() 唤醒所有等待该对象锁的线程。
public final void notifyAll();
特点:
- 必须在
synchronized代码块中调用 - 唤醒所有等待的线程
- 线程竞争获取锁
synchronized (lock) {
condition = true;
lock.notifyAll(); // 唤醒所有等待的线程
}
wait/notify 的使用模式
// 等待线程
synchronized (lock) {
while (!condition) { // 使用 while 而不是 if
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
// 条件满足,执行操作
}
// 通知线程
synchronized (lock) {
condition = true;
lock.notify(); // 或 notifyAll()
}
为什么使用 while 而不是 if:
- 防止虚假唤醒(spurious wakeup)
- 确保条件真正满足