引言:
在 Java 多线程编程中,
wait()
和notify()
方法是用于实现线程间通信的重要工具。它们通常与synchronized
关键字结合使用,用于协调多个线程的执行顺序,实现线程间的协作。本文将详细介绍wait()
和notify()
方法的使用方式,并通过示例说明其在多线程编程中的应用场景。
完成这个协调⼯作, 主要涉及到三个⽅法
- wait() / wait(long timeout): 让当前线程进⼊等待状态.
- notify() / notifyAll(): 唤醒在当前对象上等待的线程
一、wait() 和 notify() 方法概述
-
wait()
: 当一个线程执行了wait()
方法后,它会释放当前持有的对象锁,并进入等待状态,直到其他线程调用了相同对象上的notify()
或notifyAll()
方法将其唤醒。 -
notify()
: 用于唤醒一个正在等待的线程。调用notify()
方法会随机唤醒等待队列中的一个线程,并使其从wait()
方法返回。 -
notifyAll()
: 用于唤醒所有正在等待的线程。调用notifyAll()
方法会唤醒等待队列中的所有线程,使它们从wait()
方法返回。
二、wait() 和 notify() 方法的使用方式
在使用 wait()
和 notify()
方法时,通常需要遵循以下几个步骤:
-
wait()
方法必须在同步块或同步方法中调用,即在持有对象锁的情况下调用。 -
调用
wait()
方法后,线程会释放对象锁,并进入等待状态。 -
另一个线程在适当的时机调用相同对象上的
notify()
或notifyAll()
方法,唤醒等待中的线程。 -
被唤醒的线程会重新竞争对象锁,一旦获取到对象锁,它会从
wait()
方法返回,并继续执行。
三、示例:生产者-消费者模式
下面是一个经典的生产者-消费者模式的示例,演示了如何使用 wait()
和 notify()
方法来实现线程间的协作:
public class ProducerConsumer {
private List<Integer> buffer = new ArrayList<>();
private final int CAPACITY = 5;
public void produce() throws InterruptedException {
synchronized (this) {
while (buffer.size() == CAPACITY) {
wait(); // 缓冲区已满,生产者等待
}
int value = new Random().nextInt();
buffer.add(value);
System.out.println("Produced: " + value);
notify(); // 唤醒消费者线程
}
}
public void consume() throws InterruptedException {
synchronized (this) {
while (buffer.isEmpty()) {
wait(); // 缓冲区为空,消费者等待
}
int value = buffer.remove(0);
System.out.println("Consumed: " + value);
notify(); // 唤醒生产者线程
}
}
}
在这个示例中,produce()
方法负责生产数据并将其放入缓冲区,而 consume()
方法负责从缓冲区中消费数据。通过调用 wait()
和 notify()
方法,实现了生产者和消费者线程间的协作,避免了数据竞争和线程间通信的问题。
总结:
wait()
和notify()
方法是 Java 多线程编程中非常重要的工具,能够实现线程间的协作和通信。合理地使用这两个方法可以帮助我们编写出高效、可靠的多线程程序,提高程序的性能和可维护性。在实际应用中,需要谨慎地使用这两个方法,避免出现死锁和数据不一致等问题。