Why is this an issue?

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.

How to fix it

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.

Code examples

Noncompliant code example

private void performSomeAction(Object syncValue) {
  while (!suitableCondition()){
    syncValue.wait(); // Noncompliant, not being inside a `synchronized` block, this will raise an IllegalMonitorStateException
  }
  ... // Perform some action
}

Compliant solution

private void performSomeAction(Object syncValue) {
  synchronized(syncValue) {
    while (!suitableCondition()){
      syncValue.wait(); // Compliant, the `synchronized` block guarantees ownership of syncValue's monitor
    }
    ... // Perform some action
  }
}

References