Не работает notify() в моем коде

Пытаюсь использовать notify и wait, но что-то не выходит.

private boolean captcha = false;

@EventHandler
    public void onLogin(ServerConnectEvent var1) throws InterruptedException {
        while(!captcha)
        {
          wait();
        }
        System.out.print("Нотифи2");
    }

    @EventHandler
    public void onCommand(ChatEvent var1) {
         ProxiedPlayer p = (ProxiedPlayer) var1.getSender();
         if(var1.getMessage().startsWith("привет")) {
             captcha = true;
             notify();
             System.out.print("Нотифи");
             var1.setCancelled(true);
             
         }

При выполнении команды "привет" System.out.print("Нотифи"); не выполняется, значит он останавливается на notify();, по почему так? Что не правльно?


Ответы (1 шт):

Автор решения: стасевич

wait, notify методы, принадлежат Object, чтобы их использовать надо получить блокировку объекта (lock).

и на будущее, в вопрос надо писать конкретную проблему к примеру exception а не абстрактное описание - не работает.

для примера вырезал кусочек твоего кода и пробую отдельно запустить

public class Test {
    public void test() throws InterruptedException {

            while (true) {
                System.out.println("start");
                wait(1000);
                System.out.println("end");
                break;
            }
            System.out.println("Нотифи2");
        }


    public static void main(String[] args) throws InterruptedException {
        Test test = new Test();
        test.test();

    }
}

в итоге получаем

 Exception in thread "main" java.lang.IllegalMonitorStateException: current thread is not owner   

далее идём в гугл, и пишем ошибку и ищем что-то похожее на stackoverflow либо на baeldung.com тоже крайне полезный сайт. открываем ссылку
https://www.baeldung.com/java-illegalmonitorstateexception

и читаем
3. How to Fix It
нужно выполнять каждый вызов методов wait (), notify () и notifyAll () в синхронизированном блоке.

добавляем в сигнатуру synchronized

public synchronized void  test() throws InterruptedException  

вывод

start
end
Нотифи2

либо оборачиваем код в блок synchronized

 public void test() throws InterruptedException {
        synchronized (this) {
            while (true) {
                System.out.println("start");
                wait(1000);
                System.out.println("end");
                break;
            }
            System.out.println("Нотифи2");
        }
    }
→ Ссылка