Java wait() 和 notify() 方法

在 Java 中,wait()notify() 方法是用于线程间通信的基本机制,它们可以协调多个线程之间的协作。这些方法都属于 Object 类,因此可以在任何对象上调用。下面详细介绍它们的使用方法和原理。

wait() 方法

wait() 方法用于让当前线程进入等待状态,直到另一个线程调用同一个对象的 notify()notifyAll() 方法来唤醒它。wait() 方法必须在同步块或同步方法中调用,否则会抛出 IllegalMonitorStateException 异常。

示例
class SharedResource {
    public synchronized void waitMethod() {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting.");
            wait();
            System.out.println(Thread.currentThread().getName() + " is resumed.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void notifyMethod() {
        System.out.println(Thread.currentThread().getName() + " is notifying.");
        notify();
    }
}

public class WaitNotifyExample {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();

        Thread thread1 = new Thread(resource::waitMethod, "Thread 1");
        Thread thread2 = new Thread(resource::notifyMethod, "Thread 2");

        thread1.start();

        try {
            Thread.sleep(1000); // Ensure thread1 starts and waits
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread2.start();
    }
}

notify() 方法

notify() 方法用于唤醒一个正在等待该对象监视器的线程。如果有多个线程在等待,那么 notify() 将随机唤醒其中一个线程。被唤醒的线程必须重新获取对象的监视器锁,才能继续执行。

notifyAll() 方法

notifyAll() 方法用于唤醒所有等待该对象监视器的线程。被唤醒的线程将会竞争对象的监视器锁,只有一个线程能成功获得锁并继续执行,其他线程会继续等待。

示例
class SharedResource {
    public synchronized void waitMethod() {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting.");
            wait();
            System.out.println(Thread.currentThread().getName() + " is resumed.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void notifyAllMethod() {
        System.out.println(Thread.currentThread().getName() + " is notifying all.");
        notifyAll();
    }
}

public class WaitNotifyAllExample {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();

        Thread thread1 = new Thread(resource::waitMethod, "Thread 1");
        Thread thread2 = new Thread(resource::waitMethod, "Thread 2");
        Thread thread3 = new Thread(resource::notifyAllMethod, "Thread 3");

        thread1.start();
        thread2.start();

        try {
            Thread.sleep(1000); // Ensure thread1 and thread2 start and wait
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread3.start();
    }
}

注意事项

  1. 必须在同步块中调用wait()notify()notifyAll() 必须在同步块或同步方法中调用,因为它们需要持有对象的监视器锁。
  2. 释放锁:调用 wait() 方法时,线程会释放对象的监视器锁,进入等待状态。被唤醒后,线程需要重新获得监视器锁,才能继续执行。
  3. 唤醒顺序不确定notify() 随机唤醒一个等待的线程,而 notifyAll() 唤醒所有等待的线程,唤醒的顺序取决于线程调度器。

总结

  • wait():让线程进入等待状态,释放监视器锁。
  • notify():唤醒一个正在等待该对象监视器的线程。
  • notifyAll():唤醒所有正在等待该对象监视器的线程。

这些方法在多线程编程中非常重要,可以实现线程间的协作和通信。通过合理使用 wait()notify() 方法,可以避免竞争条件和死锁等问题,编写出更加健壮的多线程应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值