notify()和notifyAll()之间的微妙区别
notify()和notifyAll()之间的主要区别在于它们唤醒的等待线程数量(一个与所有),这提出了另一个问题:
为什么总是有一个线程重新获取对象锁吗?
一般情况下,notify()和notifyAll()都没有指定选择哪个等待线程来重新获取锁。 JVM 或系统线程调度程序会进行此选择,该选择可能是不确定的。
需要notifyAll()
但是,在某些场景下使用notify()可能会导致死锁,如下例所示:
生产者/消费者类notification()
public class ProducerConsumer { private final int MAX_SIZE = 1; // Buffer size private List<Object> buf = new ArrayList<>(); public synchronized void put(Object o) { while (buf.size() == MAX_SIZE) { wait(); } buf.add(o); notify(); } public synchronized Object get() { while (buf.size() == 0) { wait(); } Object o = buf.remove(0); notify(); return o; } }
死锁场景:
因此,三个线程都无限期地等待,导致死锁。
解决方案:notifyAll()
为了解决这个死锁,必须在生产者/消费者代码中使用notifyAll()而不是notify()。这可以确保所有等待线程都被唤醒,防止死锁。
建议:
对于大多数场景,notifyAll() 是首选方法,因为它可以避免潜在的死锁。如果特定场景只需要唤醒一个特定的等待线程,那么notify()可谨慎使用。
以上是为什么一个线程在notify()或notifyAll()之后总是重新获取对象锁?的详细内容。更多信息请关注PHP中文网其他相关文章!