Анализатор обнаружил, что методы 'wait', 'notify', 'notifyAll' могут быть вызваны в несинхронизированном контексте.
public void someMethod() { notify(); } public void anotherMethod() throws InterruptedException { wait(); }
Методы 'wait', 'notify', 'notifyAll' работают с монитором объекта, по которому происходит синхронизация. То есть их вызов корректен только в синхронизированном контексте и только на объекте, по которому происходит синхронизация.
В случае, если методы 'wait', 'notify' или 'notifyAll' вызвать в несинхронизированном контексте или не на том объекте, по которому синхронизация происходит, произойдёт выброс исключения 'IllegalMonitorStateException'.
Пример корректного использования в 'synchronized' блоке:
private final Object lock = new Object(); public void someCorrectMethod() { synchronized (lock) { lock.notify(); } }
Поскольку синхронизация идёт по объекту 'lock', вызов метода 'notify' корректен только на объекте 'lock'.
Корректное использование в 'synchronized' методе:
public synchronized void anotherCorrectMethod() { notifyAll(); }
Фрагмент выше эквивалентен следующему:
public void anotherCorrectMethod() { synchronized (this) { notifyAll(); } }
Из этого следует, что в данной ситуации метод 'notifyAll' корректно вызывать только на 'this' объекте.
Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки при работе с многопоточными примитивами (интерфейсами запуска потоков на выполнение, синхронизации и обмена данными между потоками и пр.). |
Данная диагностика классифицируется как: