大家好,我是小米,一名喜欢分享技术的程序员。今天我想和大家聊一聊 Java 中的 notify 和 notifyAll 的区别。

锁池和等待池

在 Java 中,每个对象都有一个锁,它是用来控制对该对象的访问的。当一个线程需要访问该对象时,它必须先获得该对象的锁。如果该对象已经被其他线程锁定,则当前线程将被阻塞并等待该对象的锁释放。

那么问题来了,当一个线程等待某个对象的锁时,它会进入哪个池子呢?这里我们要了解两个概念:锁池和等待池。

锁池是指那些被锁定的对象,等待池则是指那些正在等待锁定的对象。在 Java 中,线程可以调用 Object 类的 wait() 方法将自己放到等待池中,同时释放该对象的锁。当其他线程释放了该对象的锁时,等待池中的线程将竞争该对象的锁。

notify 和 notifyAll 的区别

接下来我们来说一下 notify 和 notifyAll 的区别。这两个方法都是用来唤醒等待池中的线程的。notify 方法会随机地唤醒一个等待池中的线程,而 notifyAll 方法则会唤醒所有等待池中的线程。

使用 notify 或 notifyAll 的场景取决于具体的应用需求。当只有一个线程需要被唤醒时,我们可以使用 notify 方法,这样可以避免唤醒不必要的线程,提高程序效率。而当多个线程都需要被唤醒时,我们可以使用 notifyAll 方法,这样可以确保所有等待池中的线程都得到唤醒,避免出现死锁的情况。

案例演示

下面我们来看一个电商项目的实际案例。假设有一个订单系统,订单在提交后需要等待库存的释放,当库存释放后,订单才能被处理。我们可以使用 wait 和 notify 方法实现这个功能,如下所示:

notifyItemRemoved后position不对 notifyfor_Java

 

上面的代码中,submit 方法需要等待库存的释放,如果库存为0,则调用 wait 方法将线程放入等待池中。当库存释放后,调用releaseInventory 方法唤醒一个等待池中的线程,将其移到锁池中。

但是,如果存在多个等待池中的线程,我们只唤醒一个线程可能会导致其他线程直接进入等待池,无法得到处理。因此,我们可以使用 notifyAll 方法来唤醒所有等待池中的线程,确保所有的订单都能够得到处理。

notifyItemRemoved后position不对 notifyfor_唤醒等待_02

 

上面的代码中,我们使用了 notifyAll 方法来唤醒所有等待池中的线程,确保所有的订单都能够得到处理。

总结

总结一下,Java 中的 notify 和 notifyAll 方法都是用来唤醒等待池中的线程的。notify 方法会随机地唤醒一个等待池中的线程,而 notifyAll 方法则会唤醒所有等待池中的线程。使用哪个方法取决于具体的应用需求。当只有一个线程需要被唤醒时,我们可以使用 notify 方法;而当多个线程都需要被唤醒时,我们可以使用 notifyAll 方法。

END