wait()必须在synchronized块或方法中调用,由持有对象锁的线程执行,否则抛illegalmonitorstateexception;需配合while循环检查条件,且notify/notifyall须作用于同一对象。

Java 中 wait() 方法必须在同步上下文(即 synchronized 块或 synchronized 方法)中调用,且必须由当前持有对象锁的线程来调用,否则会抛出 IllegalMonitorStateException。
必须在 synchronized 中调用
wait() 是 Object 类的方法,它会让当前线程释放该对象的锁,并进入等待状态,直到被唤醒(notify() 或 notifyAll())或超时。这个操作天然依赖锁的持有关系:
- 没有 synchronized,线程没拿到锁,调用
wait()直接报错 - 有 synchronized(比如
synchronized(obj) { obj.wait(); }),才表示当前线程正持有obj的监视器锁,此时调用合法
只能在目标对象上调用
调用 obj.wait(),意味着让当前线程在 obj 的等待队列中挂起。因此:
- 不能对 null 调用,否则 NPE
- 不能对其他线程持有的对象调用(除非你恰好也持有了它的锁)
- 常见错误:在
this上同步,却对别的对象调用wait()—— 锁和 wait 对象不一致,照样报异常
推荐写法:配合 while 循环检查条件
wait() 可能被虚假唤醒(spurious wakeup),所以不能只用 if 判断条件:
- ✅ 正确:
while (!condition) { obj.wait(); } - ❌ 危险:
if (!condition) { obj.wait(); } - 唤醒后应重新检查业务条件是否真正满足,再决定是否继续执行
注意唤醒与通知的匹配
调用 wait() 后,线程进入的是该对象的等待队列;只有对该同一对象调用 notify() 或 notifyAll(),才能将其唤醒:
- 在
synchronized(obj)块里调用了obj.wait() - 就必须在另一个
synchronized(obj)块里调用obj.notify()才有效 - 若通知的是另一个对象(如
other.notify()),当前线程不会被唤醒
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











