java中wait()不直接等待特定条件,需配合synchronized、while循环和notify()/notifyall()实现经典“等待-通知”机制;必须用while而非if防虚假唤醒;wait必须在synchronized块中调用且持有对象锁;通知前须先更新共享状态再notify;多线程场景推荐notifyall();现代开发优先使用condition、blockingqueue等并发工具替代wait/notify。

Java 中 wait() 方法本身不直接等待“特定条件”,它只是让当前线程释放锁并进入等待状态;真正实现“等待特定条件”需要配合 synchronized 块、while 循环和 notify()/notifyAll() 使用——这是经典的“等待-通知”机制。
必须用 while 而不是 if 检查条件
唤醒后条件可能仍未满足(虚假唤醒或多个线程竞争),所以要用 while 循环反复检查:
- 错误写法(可能导致跳过条件检查):
if (!condition) { wait(); } - 正确写法:
while (!condition) { wait(); } - 每次从
wait()返回,都需重新判断条件是否成立,否则可能出错
wait 必须在 synchronized 块中调用
wait() 是 Object 的实例方法,调用前必须持有该对象的监视器锁:
- 否则抛出
IllegalMonitorStateException - 典型结构:
synchronized (lock) { while (!ready) { lock.wait(); } } - 锁对象(如
lock)需与notify()调用时使用的对象一致
通知方要修改条件并显式唤醒
仅调用 notify() 或 notifyAll() 不够,必须先更新共享状态,再通知:
- 例如:
synchronized (lock) { ready = true; lock.notifyAll(); } - 避免“通知丢失”:若先 notify 后设条件,等待线程可能已醒来但看到
ready == false,又陷入等待 - 多消费者/生产者场景推荐用
notifyAll(),避免某些线程永远不被唤醒
推荐使用 java.util.concurrent 工具替代手写 wait/notify
手动管理 wait/notify 易出错,JDK 提供更安全、语义更清晰的高级工具:
-
Condition(配合ReentrantLock):支持多个等待队列,await()/signal()语义明确 -
BlockingQueue(如ArrayBlockingQueue):内置线程安全的“存/取”阻塞逻辑 -
CountDownLatch、CyclicBarrier、Phaser:适用于协调多线程到达某状态 - 现代代码优先考虑这些,而非裸用
wait/notify
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











