notify()

线程调用notify()或者notifyAll()后,线程不会释放它自己的锁,直到该synchronized包裹的方法执行完以后,它会释放锁,所以notify()和notifyAll()一般会放在同步代码块儿的最后一行

notify()和notifyAll()需要包裹synchronized代码块儿里面的

Java 中 notify 和 notifyAll 的区别

唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。

当你调用 notify 时,只有一个等待线程会被唤醒而且它不能保证哪个线程会被唤醒,这取决于线程调度器。虽然如果你调用 notifyAll 方法,那么等待该锁的所有线程都会被唤醒,但是在执行剩余的代码之前,所有被唤醒的线程都将争夺锁定,这就是为什么在循环上调用 wait,因为如果多个线程被唤醒,那么线程是将获得锁定将首先执行,它可能会重置等待条件,这将迫使后续线程等待。因此,notify 和 notifyAll 之间的关键区别在于 notify()只会唤醒一个线程,而 notifyAll 方法将唤醒所有线程。

何时在 Java 中使用 notify 和 notifyAll

如果所有线程都在等待相同的条件,并且一次只有一个线程可以从条件变为 true,则可以使用 notify over notifyAll。

在这种情况下,notify 是优于 notifyAll 因为唤醒所有这些因为我们知道只有一个线程会受益而所有其他线程将再次等待,所以调用 notifyAll 方法只是浪费 CPU。

尽可能用notifyall(),谨慎使用notify(),因为notify()只会唤醒一个线程,我们无法确保被唤醒的这个线程一定就是我们需要唤醒的线程,可能我想通知唤醒的线程没有通知到.

notify/notifyAll和wait方法,在使用这3个方法时,必须处于synchronized代码块或者synchronized方法中,否则就会抛出IllegalMonitorStateException异常,这是因为调用这几个方法前必须拿到当前对象的监视器monitor对象,也就是说notify/notifyAll和wait方法依赖于monitor对象,在前面的分析中,我们知道monitor 存在于对象头的Mark Word 中(存储monitor引用指针),而synchronized关键字可以获取 monitor ,这也就是为什么notify/notifyAll和wait方法必须在synchronized代码块或者synchronized方法调用的原因.