Уведомление об исключении java.lang.IllegalMonitorStateException Locks

Я пробовал сценарий ожидания и уведомления, получая -> Исключение в потоке "Thread-1" java.lang.IllegalMonitorStateException при вызове уведомления.

метод ожидания освобождает блокировку, поэтому поток B может выполнить и из потока B я вызываю lock.notify для потока A.

Не могли бы вы помочь мне в этом?

class SynchronizedCodee  {

    int a = 5;
    Lock lock = new ReentrantLock();
    public void threadA()
    {
        lock.lock();
        try {
            lock.wait();
            System.out.println("A = "+a);
        } catch (Exception e) {
            // TODO Auto-generated catch block
//          e.printStackTrace();
        }
        finally
        {
            lock.unlock();
        }
    }

    public void threadB()
    {
        if(lock.tryLock())
        {
        this.a = 11;
        System.out.println("B = "+a);
                lock.notify(); // getting erro over here
        }
        else
        {
            System.out.println("didn't managed to get a lock");
        }
    }

}
class ThreadA extends Thread{
    SynchronizedCodee s;
    public ThreadA(SynchronizedCodee s) {
        this.s = s;
    }
    public void run()
    {
        s.threadA();
    }
}

class ThreadB extends Thread{
    SynchronizedCodee s;
    public ThreadB(SynchronizedCodee s) {
        this.s = s;
    }
    public void run()
    {
        s.threadB();
    }
}
public class SynchronizedCode{
    public static void main(String ag[]) throws InterruptedException
    {
        SynchronizedCodee s = new SynchronizedCodee();
        ThreadA t1  = new ThreadA(s);
        ThreadB t2  = new ThreadB(s);
        t1.start();
        Thread.sleep(100);
        t2.start();

    }
}


person Shelly    schedule 29.03.2020    source источник
comment
Все объекты Java могут использоваться в качестве замков. Прямо сейчас вы вызываете wait и notify для объекта lock без синхронизации с ним - поэтому вы получаете исключение. Обычно вы либо используете методы notify и wait для некоторого объекта общей блокировки, либо экземпляры Lock с его методами lock и unlock И экземплярами Condition, которые создаются из ваших Lock экземпляров.   -  person Michał Krzywański    schedule 29.03.2020
comment
Вы перепутали старый низкий уровень wait/notify с высокоуровневым механизмом Lock.   -  person Kayaman    schedule 29.03.2020


Ответы (1)


Вы вызываете ожидание и уведомляете о явных объектах блокировки, и это незаконно. Если вы используете явные объекты блокировки, вы должны использовать связанный с ним объект Condition. Затем вы должны вызывать методы condition.await и condition.signalAll вместо wait и notify. Вот идиома для использования явных блокировок в вашем конкретном сценарии.

final Condition setA = lock.newCondition();
public void threadA() {
    lock.lock();
    try {
        while (a == 5)
            setA.await();
        System.out.println("A = " + a);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        lock.unlock();
    }
}

public void threadB() {
    lock.lock();
    try {
        this.a = 11;
        System.out.println("B = " + a);
        setA.signalAll();
    } finally {
        lock.unlock();
    }
}

И эта программа производит следующий вывод:

B = 11
A = 11
person Ravindra Ranwala    schedule 29.03.2020
comment
Да, пробовали с интерфейсом Condition, и он работает, поэтому мы вообще не можем использовать ожидание и уведомление с объектом блокировки? - person Shelly; 29.03.2020
comment
@ Шелли, ты могла технически, но было бы очень глупо (на самом деле было бы неправильно) смешивать их. - person Kayaman; 29.03.2020