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以后,这是关键)。
若是很不幸的话,生产者产生了一条消息后就再也不生产消息了,那么消费者就会一直挂起,没法消费,形成死锁。code
老是让give/notify和take/wait为原子操做。wait/notify是线程之间的通讯,他们存在竞态,咱们必须保证在知足条件的状况下才进行wait。换句话说,若是不加锁的话,那么wait被调用的时候可能wait的条件已经不知足了(如上述)。因为错误的条件下进行了wait,那么就有可能永远不会被notify到,因此咱们须要强制wait/notify在synchronized中。rem