java中wait()原生支持超时等待,需在synchronized块中调用,超时后仍需循环检查条件;与sleep不同,wait释放锁且可被notify唤醒;lock+condition提供更灵活的await机制。

Java 中 wait() 方法本身支持带超时的等待,通过重载版本 wait(long timeout) 或 wait(long timeout, int nanos) 实现。它不是“额外实现”,而是原生提供的能力,关键在于正确配合 synchronized 块和条件判断使用。
必须在 synchronized 代码块中调用
wait() 是 Object 的 final 方法,只能在持有对象监视器(即已进入 synchronized 块或方法)的前提下调用,否则抛出 IllegalMonitorStateException。超时参数单位是毫秒,nanos 参数用于纳秒级精度补充(实际精度受系统限制)。
- 超时时间设为 0 表示无限等待(等同于无参
wait()) - 超时时间小于 0 会抛出
IllegalArgumentException - 即使超时,线程被唤醒后仍需重新获取锁才能继续执行
超时后需手动检查条件是否满足
超时返回不表示条件已达成,只是等待被中断或时间到。典型用法是配合循环检查“守卫条件”(guard condition),避免虚假唤醒或超时误判:
synchronized (lock) {
while (!conditionMet()) {
try {
lock.wait(5000); // 等待最多 5 秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
// 此时 conditionMet() 为 true,安全执行后续逻辑
}
注意:不能用 if 替代 while,否则可能跳过条件检查。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
与 sleep 的本质区别
wait() 释放锁并进入等待队列;Thread.sleep() 不释放任何锁,仅让出 CPU。超时等待场景下若需释放锁以便其他线程修改共享状态,必须用 wait();若只是延时且不涉及协作,用 sleep() 更简单。
-
wait()可被notify()/notifyAll()提前唤醒 -
sleep()只能靠时间结束或被中断 - 二者都响应中断,但
wait()被中断时会清除中断状态(需手动恢复)
替代方案:Lock + Condition 更灵活
从 Java 5 开始,java.util.concurrent.locks.Condition 提供了类似但更可控的 await 机制:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while (!conditionMet()) {
if (!condition.await(5, TimeUnit.SECONDS)) {
break; // 超时返回 false
}
}
} finally {
lock.unlock();
}
优势包括:可绑定多个条件变量、支持公平锁、await 可指定任意时间单位、超时返回布尔值便于判断。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










