为什么wait方法必须在同步(synchronized)代码块/方法中调用
调用wait就是释放锁,释放锁的前提是必须先获得锁,先获得锁才能释放锁。
为什么notify,notifyall必须在同步(synchronized)代码块/方法中调用
notify,notifyall是让入口队列中的线程竞争锁,如果自身没有锁,怎么能让入口队列中的线程竞争锁呢。
wait后的代码会执行
class BlockingQueue {
Queue<String> buffer = new LinkedList<String>();
Object lock = new Object();
public void add(String data) {
buffer.add(data);
lock.notify();
}
public String take() throws InterruptedException {
while (buffer.isEmpty())
lock.wait();
return buffer.remove();
}
}
在队列为空的时候使用wait阻塞,队列中有元素的时候采用notify唤醒。但可能会出现问题
- 一个消费者调用take,发现队列是空的,
- 在消费者调用wait之前,由于cpu的调度,消费者线程被挂起,生产者调用add,然后notify
- 然后消费者调用wait,(wait调用在notify之后,)
- 如果生产者生产了一条消息之后就不再生产消息啦,那就会存在队列中有一条消息永远不会被消费。