Object.wait(long) 实现带超时线程协作需在 synchronized 块中调用,先获取锁再检查条件,超时单位为毫秒,0 表示无限等待,否则启用超时机制,避免无限阻塞并确保资源释放。

用 Object.wait(long) 实现带超时的线程协作,核心是避免线程在条件不满足时无限阻塞,同时兼顾响应性和资源释放。关键不是单纯调用 wait,而是配合正确的同步结构、条件检查和超时后的行为处理。
必须在 synchronized 块中调用 wait
wait 方法只能在持有对象锁的前提下执行,否则抛 IllegalMonitorStateException。超时参数单位是毫秒,0 表示无限等待(等同于无参 wait),非 0 值才启用超时机制。
- 先获取锁(
synchronized(obj)),再检查条件是否已满足 - obj.wait(timeoutMs)
用循环检查条件(while 而非 if)
即使设置了超时,也不能只用 if 判断一次条件。JVM 允许虚假唤醒(spurious wakeup),且超时返回不代表条件成立。必须用 while 循环重检:
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
synchronized (lock) {
while (!conditionMet()) {
try {
lock.wait(5000); // 等最多 5 秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return; // 或按需处理中断
}
}
// 此处 conditionMet() 为 true,安全执行后续逻辑
}
超时后的典型处理策略
wait 返回不等于条件达成。常见做法包括:
- 重试有限次数:比如最多等 3 次,每次 2 秒,总超时 6 秒
- 降级处理:如获取不到最新数据,就用缓存值或默认值继续
-
主动放弃并报错:记录日志,抛出
TimeoutException或返回特殊状态 - 触发补偿动作:比如通知其他线程重新准备资源、清理临时状态
注意 notify/notifyAll 的协作时机
仅靠 wait 超时不能解决协作问题,生产者必须在条件满足后及时唤醒等待者:
- 唤醒操作也必须在 synchronized 块中完成(与 wait 同一锁)
- 优先用
notifyAll(),除非能严格保证只有一个等待线程且唤醒目标明确 - notify 应在修改共享状态 之后、释放锁 之前 执行,确保等待线程醒来时看到最新状态










