The Object.wait(…), Object.notify() and Object.notifyAll() methods are used in multithreaded environments
to coordinate interdependent tasks that are performed by different threads. These methods are not thread-safe and by contract, they require the
invoking Thread to own the object’s monitor. If a thread invokes one of these methods without owning the object’s monitor an
IllegalMonitorStateException is thrown.
To become the owner of an object’s monitor Java provides the synchronized keyword. In other words, calling
Object.wait(…), Object.notify() and Object.notifyAll() on a given object should only be done from code
synchronized on the same object.
For example, the call to someObject.wait(…) should be wrapped in a synchronized(someObject){ … } block. If
wait or notify are invoked on this, then the entire method can be marked as synchronized.
private void performSomeAction(Object syncValue) {
while (!suitableCondition()){
syncValue.wait(); // Noncompliant, not being inside a `synchronized` block, this will raise an IllegalMonitorStateException
}
... // Perform some action
}
private void performSomeAction(Object syncValue) {
synchronized(syncValue) {
while (!suitableCondition()){
syncValue.wait(); // Compliant, the `synchronized` block guarantees ownership of syncValue's monitor
}
... // Perform some action
}
}