wait()必须在synchronized块内调用,释放当前对象锁并使线程进入WAITING状态,需配合while循环条件检查、notify/notifyAll唤醒及超时重载使用。

在 Java 多线程中,wait() 方法必须在 synchronized 同步块或同步方法内调用,它会立即释放当前线程持有的对象锁,并使线程进入该对象的等待队列(Wait Set),直到被其他线程调用 notify() 或 notifyAll() 唤醒,或被中断、超时。
wait() 必须配合 synchronized 使用
wait() 是 Object 类的实例方法,调用前线程必须已获取该对象的监视器锁(即处于 synchronized 代码块/方法中)。否则会抛出 IllegalMonitorStateException。
- 释放的是当前 synchronized 锁定的那个对象的锁,不是所有锁
- 例如:
synchronized(obj) { obj.wait(); }→ 释放的是obj的锁 - 若在 synchronized(this) 中调用 wait(),释放的是当前实例锁
wait() 后线程状态与唤醒机制
调用 wait() 后,线程从 RUNNABLE 状态变为 WAITING(或 TIMED_WAITING),并离开同步块,但仍在该对象的等待队列中挂起。它不会自动重新竞争锁,需被显式唤醒后才尝试重新获取锁。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
notify():随机唤醒一个等待该对象锁的线程 -
notifyAll():唤醒所有等待该对象锁的线程(更安全,推荐) - 被唤醒的线程需重新竞争对象锁,获得锁后才能从
wait()返回,继续执行
务必用 while 循环检查条件,避免虚假唤醒
即使没有被显式 notify,线程也可能因系统原因被“虚假唤醒”。因此不能用 if 判断条件,而要用 while 循环重检业务条件是否真正满足。
立即学习“Java免费学习笔记(深入)”;
synchronized (lock) {
while (!conditionMet) {
lock.wait();
}
// 条件满足,安全执行后续逻辑
}
- 条件变量(如 flag、queue.isEmpty())必须在同步块内读取和修改
- 每次唤醒后都重新判断,确保状态符合预期
- 这是 wait-notify 协作模式的标准写法,缺一不可
注意 wait() 的三种重载形式
wait() 有三个版本,行为略有不同:
-
wait():无限等待,直到被 notify/notifyAll 或中断 -
wait(long timeout):最多等待 timeout 毫秒,超时后自动返回(仍需检查条件) -
wait(long timeout, int nanos):更精细的纳秒级超时控制(实际精度取决于 JVM 和 OS) - 所有版本都会释放锁;超时返回后线程仍需重新竞争锁

















