Java Illegal Monitor State Exception

I am trying to print odd and even numbers alternately using two different threads that coordinate among themselves using wait and notify and also using a lock.

public class OddEvenPrinter {
    private Object lock = new Object();
    private boolean printFlag = false;


     void printOdd() throws InterruptedException {
         for(int i=1; i < 25; i=i+2){
             synchronized (lock){
                 while(printFlag){
                     wait();
                 }
                 System.out.println(i + "********  PRINT ODD  ");
                 notifyAll();
             }
         }
    }

    void printEven() throws InterruptedException {
        for(int i=0; i < 25; i=i+2){
            synchronized (lock){
                while(!printFlag){
                    wait();
                }
                System.out.println(i + "********  PRINT EVEN  ");
                notifyAll();
            }
        }
    }

I have a Driver program to verify this. Can we not use synchronized block in a for loop. I am getting Illegal Monitor State exception.

public static void main(String[] args) throws InterruptedException {
        OddEvenPrinter printer = new OddEvenPrinter();
        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    printer.printEven();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    printer.printOdd();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        a.start();
        b.start();

        System.out.println("All DONE.....");
    }

>Solution :

You are synchronizing on lock object, but calling wait() which equivalent of this.wait().

Notice that this represents different object that one held by lock and has separate monitor. You never acquired monitor of this object so you can’t release it with this.wait().

Use lock.wait() and lock.notifyAll() instead.

Leave a Reply