1

Was trying to practice producer and consumer using a simple counter in java. Not sure why I am getting a Illegal Monitor State exception on this piece of code.

I have counter rest and counter consume methods which run in their own thread. The counter itself is a static int volatile field . The counter class also gives you a lock to

If I change the wait naotify to the following:

Counter.lock.notify();
Counter.lock.wait();

The code works. Dosen't wait() and notify() automatically takes the reference of the lock synchronize is on?

Producer Class

package multithreading;


public class CounterProducer implements Runnable {


public void run() {

    try {   incrCounter();   } catch (InterruptedException e) {            e.printStackTrace();        }
}

public void incrCounter() throws InterruptedException {


    while (true) {
        synchronized (Counter.lock) {
            if (Counter.counter < 1) {
                System.out.println("Counter Reset");
                Counter.counter = 10;
                notify();
                wait();
            }


        }
    }


}

}

Consumer Class

package multithreading;


public class CounterConsumer implements Runnable {


    public void run() {

        try {   consumeCounter();   } catch (InterruptedException e) {            e.printStackTrace();        }
    }

    public void consumeCounter() throws InterruptedException {


        while (true) {
            synchronized (Counter.lock) {
                if (Counter.counter > 0) {
                    System.out.println("Consumed");
                    Counter.counter--;
                    notify();
                    wait();
                }


            }
        }


    }

}

The Counter

public class Counter {

    public static volatile int counter;

    public static final Object lock = new Object();

}

The Counter

public class CounterRunner {

    public static void main(String[] args) {

        Thread con = new Thread(new CounterConsumer());
        Thread prod = new Thread(new CounterProducer());

        con.start();
        prod.start();

    }


}

The Runner

public class CounterRunner {

    public static void main(String[] args) {

        Thread con = new Thread(new CounterConsumer());
        Thread prod = new Thread(new CounterProducer());

        con.start();
        prod.start();

    }


}
Sameer
  • 757
  • 1
  • 14
  • 35

1 Answers1

2

If I change the wait naotify to the following, the code works:

Counter.lock.notify();
Counter.lock.wait();

Every Java method is either a static method of some class or an instance method of some object. If you see a method call that does not contain an explicit class name or object reference, then it is an implicit call to a method belonging to the this object.

That is to say, notify() means the same thing as this.notify(), and wait() means this.wait().

this, refers to the CounterProducer instance when it appears in your CounterProducer.incrCounter() method, and it refers to the CounterConsumer instance when it appears in your CounterConsumer.consumeCounter() method.

Community
  • 1
  • 1
Solomon Slow
  • 25,130
  • 5
  • 37
  • 57