Object.wait(long timeout)必须在synchronized块中调用,超时后需循环检查条件是否满足,配合notify/notifyAll使用,并妥善处理InterruptedException。

Java中 Object.wait(long timeout) 的超时自动唤醒机制,是让线程在等待某个条件满足时,不会无限期挂起,而是最多等待指定毫秒数后自动恢复执行。关键在于它必须在同步块(synchronized)中调用,且唤醒不等于条件一定成立——超时后需手动检查条件是否满足,否则应继续等待或处理超时逻辑。
必须配合 synchronized 使用
调用 wait() 前,当前线程必须持有该对象的监视器锁,否则会抛出 IllegalMonitorStateException。超时参数单位是毫秒,支持 0(等同于无参 wait(),即永久等待)和正整数。
- 正确写法:synchronized(obj) { obj.wait(5000); }
- 错误写法:直接调用
obj.wait(5000)(未加锁) - 注意:超时时间是“至少等待”,实际唤醒可能略晚于设定值(受系统调度影响)
超时后要重新判断条件
wait(long) 返回不代表条件已满足,可能是被其他线程 notify()/notifyAll() 唤醒,也可能是超时唤醒。因此必须用循环检查条件,避免虚假唤醒或条件未就绪就继续执行。
- 推荐模式:while (!condition) { obj.wait(timeout); }
- 例如:等待队列非空,不能用
if,而要用while(queue.isEmpty()) - 超时后跳出循环,可选择重试、抛异常、返回默认值或执行降级逻辑
与 notify/notifyAll 配合使用
wait() 等待的是其他线程对同一对象调用 notify() 或 notifyAll()。超时只是兜底机制,不能替代主动通知。
立即学习“Java免费学习笔记(深入)”;
- 修改共享状态后,必须在
synchronized块内调用notify()或notifyAll() - 若只用
notify(),建议确保只有一个等待线程,或使用notifyAll()避免丢失信号 - 超时唤醒后,如果条件仍不满足,可考虑再次
wait()(带新超时)或放弃等待
注意中断与异常处理
wait(long) 可被中断,会抛出 InterruptedException。即使超时未到,线程也可能因中断提前返回。务必捕获并合理处理该异常。
- 典型做法:捕获异常后恢复中断状态
Thread.currentThread().interrupt(); - 不要忽略
InterruptedException,否则上层无法感知中断意图 - 超时和中断都导致方法返回,但两者触发路径不同,业务逻辑需区分或统一处理


















