编写一个示例程序,展示如何使用 wait 方法使线程等待。
在Java中,wait()
和 notify()
方法是 Object
类的一部分,用于协调多个线程对共享资源的访问。这些方法只能在同步块或同步方法中使用,否则会抛出 IllegalMonitorStateException
。
下面是一个简单的例子,其中一个线程等待另一个线程发出通知:
public class WaitNotifyExample {
// 共享资源
private static Object lock = new Object();
private static boolean ready = false;
public static void main(String[] args) throws InterruptedException {
// 创建并启动等待线程
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
while (!ready) {
try {
System.out.println("等待线程:等待中...");
lock.wait(); // 等待通知
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("等待线程:收到通知,继续执行...");
}
});
// 启动等待线程
waitingThread.start();
// 让等待线程有机会进入等待状态
Thread.sleep(1000);
// 创建并启动通知线程
Thread notifyingThread = new Thread(() -> {
synchronized (lock) {
System.out.println("通知线程:准备通知等待线程...");
ready = true;
lock.notify(); // 发出通知
}
});
// 启动通知线程
notifyingThread.start();
}
}
在这个例子中,我们有一个共享资源 lock
和一个标志 ready
。等待线程进入同步块,并检查 ready
是否为 true
。如果不是,它调用 lock.wait()
进入等待状态,释放 lock
对象上的监视器。
然后,主线程启动通知线程,该线程也进入同步块,设置 ready
为 true
,并调用 lock.notify()
唤醒正在等待 lock
对象的线程。
请注意,在实际应用中,通常不会直接在 main
方法中处理线程,而是使用更高级的结构,如 ExecutorService
。此外,为了健壮性,通常会使用循环和条件变量来检查预期的状态变化,因为 wait()
可以被意外唤醒(即所谓的虚假唤醒)。在这个例子中,我们使用了一个简单的 while
循环来检查 ready
变量。