Java中notify与notifyAll的区别解析

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

Java面试题之多线程 Java中notify 和 notifyAll有什么区别?

回答:

在Java中,notify()notifyAll()都是用于唤醒在对象监视器上等待的线程的方法。它们的主要区别在于唤醒的线程数量和行为。

1. notify()

  • 功能notify()方法会随机唤醒一个在该对象监视器上等待的线程。如果有多个线程在等待,Java虚拟机会选择其中一个线程进行唤醒。
  • 使用场景:适用于只需要唤醒一个线程的情况,比如生产者-消费者模型中,如果有多个消费者在等待,而只需要唤醒一个消费者来处理数据。

2. notifyAll()

  • 功能notifyAll()方法会唤醒所有在该对象监视器上等待的线程。所有被唤醒的线程都会进入就绪状态,但只有一个线程会获得锁并继续执行,其他线程则会继续等待。
  • 使用场景:适用于需要唤醒所有等待线程的情况,比如当状态发生变化时,所有等待的线程都需要重新检查条件。

示例代码

class SharedResource {
    private boolean available = false;

    public synchronized void produce() {
        available = true;
        notify(); // 或者 notifyAll();
    }

    public synchronized void consume() throws InterruptedException {
        while (!available) {
            wait();
        }
        // 处理资源
        available = false;
    }
}

总结

  • 使用notify()时,只有一个等待线程会被唤醒,适合于只需要唤醒一个线程的场景。
  • 使用notifyAll()时,所有等待线程都会被唤醒,适合于需要所有线程重新检查条件的场景。

在选择使用notify()还是notifyAll()时,需要根据具体的业务逻辑和需求来决定。