Search code examples
javamultithreadingconcurrencythread-safetyjava-threads

Notify exception java.lang.IllegalMonitorStateException Locks


I was trying the wait and notify scenario, getting --> Exception in thread "Thread-1" java.lang.IllegalMonitorStateException when calling notify.

wait method releases the lock, so the threadB can execute the and from threadB i'm calling lock.notify for threadA.

Could you help me on this?

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();

    }
}


Solution

  • You are calling wait and notify on explicit lock objects and that is not legal. If you are using explicit lock objects, you have to use Condition object associated with it. Then you should call condition.await and condition.signalAll methods instead of wait and notify. Here's the idiom for using explicit locks in your particular scenario.

    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();
        }
    }
    

    And this program produces the following output:

    B = 11
    A = 11