在 java 的 synchronized 代码块中,notify() 方法用于唤醒在该对象监视器上等待的一个线程。调用此方法前必须持有该对象的锁,且通常配合 wait() 使用以实现线程间的协作。由于 notify() 是随机唤醒一个等待线程,因此实际开发中更推荐使用 notifyall() 以避免潜在的逻辑遗漏或死锁风险。

notify() 与 wait() 的标准协作流程是怎样的
标准流程要求生产者或消费者在获取锁后检查条件,若条件不满足则调用 wait() 释放锁并进入等待状态;当其他线程修改了共享状态并调用 notify() 后,等待线程被唤醒并重新尝试获取锁。这种模式确保了线程安全且避免了忙等待。

public class SharedBuffer {
private final Object lock = new Object();
private String data;
public void produce(String value) throws InterruptedException {
synchronized (lock) {
while (data != null) {
lock.wait();
}
data = value;
System.out.println("Produced: " + value);
lock.notify();
}
}
public String consume() throws InterruptedException {
synchronized (lock) {
while (data == null) {
lock.wait();
}
String val = data;
data = null;
System.out.println("Consumed: " + val);
lock.notify();
return val;
}
}
}notify() 唤醒的是哪个线程以及何时释放锁
notify() 会随机选择该对象监视器等待队列中的一个线程进行唤醒,被唤醒的线程不会立即执行,而是需要等待当前持有锁的线程退出 synchronized 块释放锁后,才能竞争并继续执行。这意味着 notify() 并不立即改变线程的执行状态,只是将其从 WAITING 转为 BLOCKED。
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
立即学习“Java免费学习笔记(深入)”;

public class NotifyTest {
public static void main(String[] args) {
Object monitor = new Object();
Thread waiter = new Thread(() -> {
synchronized (monitor) {
try {
System.out.println("Waiting...");
monitor.wait();
System.out.println("Notified!");
} catch (InterruptedException e) {}
}
});
waiter.start();
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (monitor) {
monitor.notify();
System.out.println("Notifying...");
}
}
}notify() 在没有线程等待时调用会发生什么
如果在调用 notify() 时没有任何线程处于等待状态,该方法将静默失效,不会产生任何异常或错误,也不会影响当前正在执行的代码逻辑。这要求开发者在使用时必须确保存在有效的等待者,或者通过合理的同步机制保证调用的时序正确性。

















