编写一个示例程序,展示如何使用 wait 方法使线程等待。
示例:使用 wait()
和 notify()
实现线程等待
public class WaitNotifyExample {
private static final Object lock = new Object();
private static boolean condition = false;
public static void main(String[] args) {
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
System.out.println("WaitingThread: Waiting for the condition to be true...");
try {
while (!condition) { // 条件不满足时进入等待
lock.wait();
}
System.out.println("WaitingThread: Condition is true, proceeding...");
} catch (InterruptedException e) {
System.out.println("WaitingThread: Interrupted while waiting.");
}
}
});
Thread notifyingThread = new Thread(() -> {
synchronized (lock) {
System.out.println("NotifyingThread: Setting condition to true...");
condition = true;
lock.notify(); // 唤醒等待线程
System.out.println("NotifyingThread: Notified waiting thread.");
}
});
waitingThread.start(); // 启动等待线程
try {
Thread.sleep(1000); // 模拟延迟,确保等待线程先进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyingThread.start(); // 启动通知线程
}
}
程序输出(示例):
WaitingThread: Waiting for the condition to be true...
NotifyingThread: Setting condition to true...
NotifyingThread: Notified waiting thread.
WaitingThread: Condition is true, proceeding...
程序详解:
- 关键概念:
wait()
:使当前线程等待,并释放锁。直到其他线程调用notify()
或notifyAll()
方法,线程才会被唤醒。notify()
:唤醒一个在同一个对象监视器上等待的线程。- 锁对象:
wait()
和notify()
必须在同步块或同步方法中调用,并且锁对象必须一致。
- 程序逻辑:
- 等待线程调用
lock.wait()
,进入等待状态。 - 通知线程修改共享变量
condition
,并调用lock.notify()
唤醒等待线程。 - 等待线程被唤醒后,重新检查条件变量并继续执行。
- 等待线程调用
- 注意事项:
wait()
和notify()
必须在同一个锁对象上使用。- 使用
while
循环而不是if
检查条件,避免虚假唤醒。
拓展:notifyAll()
的使用
如果有多个线程在等待同一个锁对象,可以使用 notifyAll()
唤醒所有等待线程,而不是仅唤醒一个。
修改上面的 notifyingThread
:
lock.notifyAll(); // 唤醒所有等待线程
此时,所有在 lock.wait()
上等待的线程都会被唤醒,并根据条件继续执行。