📜  Java中notify()和notifyAll()的区别(1)

📅  最后修改于: 2023-12-03 15:31:49.203000             🧑  作者: Mango

Java中notify()和notifyAll()的区别

在Java中,wait()、notify()和notifyAll()是Object类提供的方法,用于线程之间的通信。其中,wait()方法使当前线程等待,直到其它线程调用notify()或notifyAll()方法,来唤醒它;而notify()和notifyAll()则用于唤醒等待状态下的线程。

在本篇文章中,我们主要探究notify()和notifyAll()两者的区别。

区别
  • notify()方法只会唤醒一个处于等待状态下的线程,而notifyAll()方法会唤醒所有处于等待状态下的线程。

  • 由于notify()方法只能唤醒一个线程,因此无法保证哪个线程被唤醒,更不能保证这个线程比其它线程优先执行。而notifyAll()方法则可以保证所有处于等待状态下的线程被唤醒,并在资源可用时竞争执行。因此,notify()更适合于单生产者-单消费者模型,而notifyAll()则有利于多生产者-多消费者模型。

  • notify()方法可以提高程序运行效率,因为它只唤醒一个线程,这样可以避免不必要的竞争和上下文切换。而notifyAll()方法则会唤醒所有线程,导致线程竞争、上下文切换等问题。因此,notify()方法通常比notifyAll()更快。

  • 在使用notify()方法时,应该保证线程的顺序。也就是说,应该让先等待的线程先执行。例如,可以将线程的等待状态保存在一个队列中,按顺序唤醒各个线程。而调用notifyAll()方法则不存在这个问题。

示例代码

以下是一个简单的示例代码,演示notify()和notifyAll()方法的使用:

public class Example {
    private Object lock = new Object();

    public void methodNotify() { 
        synchronized(lock) {
            lock.notify();
        }
    }

    public void methodNotifyAll() {
        synchronized(lock) {
            lock.notifyAll();
        }
    }

    public void methodWait() {
        synchronized(lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在上述代码中,lock对象是同步锁。methodNotify()方法会调用lock.notify()来唤醒等待该锁的一个线程;而methodNotifyAll()方法则会调用lock.notifyAll()来唤醒所有等待该锁的线程。methodWait()方法则会在lock上等待,并且当其它线程调用lock.notify()或lock.notifyAll()时被唤醒。

总结

在Java中,notify()和notifyAll()都是线程间通信常用的方法。它们的差异在于notify()只唤醒一个线程,notifyAll()会唤醒所有等待的线程。合理使用这两种方法,不仅可以提高并发效率,避免死锁等问题,而且可以有效控制线程的执行顺序,更好地协作完成任务。