为什么wait和notify只能在synchronized中?
Posted jichi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么wait和notify只能在synchronized中?相关的知识,希望对你有一定的参考价值。
前言
wait和notify必须在synchronized块中,否则会抛出IllegalMonitorStateException。
原因
代码示例
class BlockingQueue {
Queue<String> buffer = new LinkedList<String>();
public void give(String data) {
buffer.add(data);
notify();
}
public String take() throws InterruptedException {
while (buffer.isEmpty())
wait();
return buffer.remove();
}
}
代码示例的问题所在
一个消费者调用take,发现buffer.isEmpty。
在消费者调用wait之前,由于cpu的调度,消费者线程被挂起,生产者调用give,然后notify。
然后消费者调用wait (注意,由于错误的条件判断,导致wait调用在notify之后,这是关键)。
如果很不幸的话,生产者产生了一条消息后就不再生产消息了,那么消费者就会一直挂起,无法消费,造成死锁。
关键
总是让give/notify和take/wait为原子操作。wait/notify是线程之间的通信,他们存在竞态,我们必须保证在满足条件的情况下才进行wait。换句话说,如果不加锁的话,那么wait被调用的时候可能wait的条件已经不满足了(如上述)。由于错误的条件下进行了wait,那么就有可能永远不会被notify到,所以我们需要强制wait/notify在synchronized中。
以上是关于为什么wait和notify只能在synchronized中?的主要内容,如果未能解决你的问题,请参考以下文章
notify() 和 notifyAll() 有什么区别? wait()
Java中 wait和await notify和signal的区别
面试官:为什么 wait/notify 必须与 synchronized 一起使用??
为什么 java wait/notify 必须与 synchronized 一起使用,jvm究竟做了些什么