编写一个示例程序,展示如何使用 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 对象上的监视器。

然后,主线程启动通知线程,该线程也进入同步块,设置 readytrue,并调用 lock.notify() 唤醒正在等待 lock 对象的线程。

请注意,在实际应用中,通常不会直接在 main 方法中处理线程,而是使用更高级的结构,如 ExecutorService。此外,为了健壮性,通常会使用循环和条件变量来检查预期的状态变化,因为 wait() 可以被意外唤醒(即所谓的虚假唤醒)。在这个例子中,我们使用了一个简单的 while 循环来检查 ready 变量。

发表评论

后才能评论