Why can wait and notify only be in synchronized?
preface
Wait and notify must be in the synchronized block, otherwise the illegalmonitorstateexception will be thrown.
reason
Code example
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();
}
}
What's wrong with the code example
A consumer calls take and finds buffer isEmpty。 Before the consumer calls wait, the consumer thread is suspended due to CPU scheduling, and the producer calls give and then notify. Then the consumer calls wait (note that due to the wrong condition judgment, the wait call is after notify, which is the key). If, unfortunately, the producer does not produce a message after it generates a message, the consumer will hang up and cannot consume, resulting in a deadlock.
crux
Always make give / notify and take / wait atomic operations. Wait / notify is the communication between threads. They have race state. We must ensure that we can wait only when the conditions are met. In other words, if you do not lock, the wait condition may not be satisfied when the wait is called (as described above). If you wait under the wrong conditions, you may never be notified. Therefore, we need to force wait / notify in synchronized.