notify仅唤醒等待队列中一个线程,具体由jvm调度器决定,不保证顺序;被唤醒线程需重新竞争对象锁才能继续执行,其余线程保持wait状态。

notify 方法只唤醒等待队列中的一个线程,且不保证是哪个,具体由 JVM 调度器决定。它不会清空等待队列,也不会改变其他仍在 wait 状态的线程状态;被唤醒的线程需重新竞争对象锁,成功获取后才能继续执行。
等待队列不是 FIFO,唤醒顺序不可预测
Java 中每个对象关联一个等待队列(wait set),由 JVM 内部维护。notify 并不按“先进先出”或任何显式策略选择线程,而是交由底层线程调度机制决定——可能是随机选,也可能受操作系统线程优先级、JVM 实现(如 HotSpot 的 Park/Unpark 机制)影响。因此,不能依赖 notify 唤醒特定线程,也不应假设唤醒顺序。
notify 不释放锁,被唤醒线程需重新争抢
调用 notify 时,当前线程必须持有该对象的 monitor 锁;notify 执行完后,当前线程仍持有锁,直到 synchronized 块结束或显式退出临界区。此时,被唤醒的线程从 wait 状态转为“blocked”,进入该对象的锁竞争队列,只有成功获得锁后,才会从 wait() 调用处继续向下执行。
未被唤醒的线程保持 wait 状态,不受影响
notify 只影响一个线程,其余在同一个对象上 wait 的线程继续阻塞,不会被中断或超时(除非设置了 timeout 或被 interrupt)。若需唤醒全部,应使用 notifyAll;若业务逻辑依赖精确唤醒(如生产者-消费者中只唤醒一个消费者),需配合条件判断和循环 wait 模式,避免虚假唤醒。
典型误用:不配合 while 循环检查条件
常见错误是在 wait 前用 if 判断条件,导致唤醒后直接执行后续逻辑,忽略条件是否真正满足。正确做法是:
- 始终用 while 循环包裹 wait(),每次唤醒都重新检查条件
- notify 前确保条件已更新(如修改共享状态、插入数据)
- 避免在非 synchronized 上下文中调用 notify,否则抛 IllegalMonitorStateException
不复杂但容易忽略:notify 的语义很轻量,它只是“发个信号”,真正的协调靠锁、条件变量和程序员的逻辑控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











