请解释 wait、notify、notifyAll 方法的用途及工作原理。
wait()
, notify()
和 notifyAll()
是 Java 中的 Object 类的方法,主要用于线程间的通信。
wait()
方法可以使当前的线程处于“等待”状态,同时也会让当前的线程释放它所持有的锁。
notify()
方法则会随机唤醒一个处于等待状态的线程,使其进入“可运行”状态。
notifyAll()
方法则会唤醒所有处于等待状态的线程。
这三个方法必须在 synchronized 块或者方法中使用,否则会抛出 IllegalMonitorStateException
异常。
这里举个例子,比如有一个生产者-消费者模型,生产者负责生产商品,消费者负责消费商品。当商品库存为0时,消费者需要等待生产者生产商品,这时就可以调用 wait()
方法让消费者线程等待;当生产者生产了商品后,可以调用 notify()
或 notifyAll()
方法唤醒消费者线程。
class Store {
private int product = 0;
public synchronized void produce() {
if(product >= 5) { // 如果已经有5个产品了,就等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
product++;
System.out.println("生产者生产了一件商品");
notifyAll(); // 通知等待的消费者可以取商品了
}
public synchronized void consume() {
if(product <= 0) { // 如果没有产品了,就等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
product--;
System.out.println("消费者消费了一件商品");
notifyAll(); // 通知等待的生产者可以生产商品了
}
}
在这个例子中,当商品库存达到5个时,生产者线程会调用 wait()
方法进入等待状态,并释放锁,让消费者线程有机会获取锁;当消费者消费商品后,会调用 notifyAll()
方法,唤醒等待的生产者线程,让它开始生产商品。同样的,消费者线程在商品库存为0时也会进入等待状态,等待生产者生产商品。