在 java 的 synchronized 块中,wait() 方法用于让当前线程释放对象锁并进入等待状态,直到其他线程调用同一对象的 notify() 或 notifyall() 方法将其唤醒。使用时必须确保当前线程已持有该对象的监视器锁,否则抛出 illegalmonitorstateexception;唤醒后线程需重新竞争锁,且建议始终在 while 循环中检查条件以处理虚假唤醒。

wait() 方法的基本调用位置与锁要求是什么
必须在 synchronized 代码块内部调用 wait(),因为该方法会立即释放当前持有的对象锁,允许其他线程进入同步块。如果不在同步块内调用,JVM 会直接抛出异常。调用后,当前线程的状态变为 WAITING,不再占用 CPU 资源,直到被其他线程通知。

public class WaitExample { public static void main(String[] args) { Object lock = new Object(); Thread waiter = new Thread(() -> { synchronized (lock) { try { System.out.println("Waiter waiting..."); lock.wait(); System.out.println("Waiter notified."); } catch (InterruptedException e) { e.printStackTrace(); } } }); waiter.start(); Thread notifier = new Thread(() -> { synchronized (lock) { System.out.println("Notifier notifying..."); lock.notify(); } }); notifier.start(); }} 为什么推荐使用 while 循环包裹 wait() 而不是 if 判断
使用 if 判断条件后调用 wait() 存在风险:线程被唤醒后,条件可能再次变为不满足(例如多个消费者同时被唤醒,但只有一个能获取数据)。因此,必须用 while 循环在每次唤醒后重新验证条件,只有当条件真正满足时才退出循环继续执行。这是处理虚假唤醒和竞态条件的标准做法。
立即学习“Java免费学习笔记(深入)”;

public class WhileWaitExample { private boolean ready = false; private final Object lock = new Object(); public void waitForReady() throws InterruptedException { synchronized (lock) { while (!ready) { lock.wait(); } System.out.println("Condition met, proceeding."); } } public void setReady() { synchronized (lock) { ready = true; lock.notify(); } } public static void main(String[] args) throws InterruptedException { WhileWaitExample ex = new WhileWaitExample(); Thread t = new Thread(() -> { try { ex.waitForReady(); } catch (InterruptedException e) {} }); t.start(); Thread.sleep(100); ex.setReady(); t.join(); }} wait() 被中断时会发生什么
如果线程在等待期间被其他线程调用 interrupt(),它会抛出 InterruptedException 并清除中断状态。此时线程不会自动恢复运行,而是需要捕获异常并进行处理,例如清理资源、记录日志或重新设置中断标志。这确保了程序对中断信号的响应能力,避免线程无限期挂起。


















