5

I am trying to learn Multi threading and for practice, I am trying to print odd & even number using two thread. I have created an object which will act as a lock for the both the threads. When I try to execute it throws java.lang.IllegalMonitorStateException.

class EVENODDimpl implements Runnable {
    int num;
    int temp = 0;
    Object lock = new Object();

    public EVENODDimpl( int num) {
        this.num = num;
    }

    public void run() {
        try {
            synchronized (lock) {
                while(temp<num) {
                    temp++;
                    System.out.println(Thread.currentThread().getName()+"   "+temp);
                    this.notify();
                    this.wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } 
    }
}

Main Method:

public class EVENODD {
    public static void main(String[] args) {
        int i = 10;
        EVENODDimpl ei = new EVENODDimpl(i);
        Thread t1 = new Thread( ei,"EvenThread");
        Thread t2 = new Thread( ei,"OddThread");
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
crazyStart
  • 127
  • 1
  • 10
  • I think the problem is that you are synchronizing on an object but then calling `notify` and `wait` on a different one. – Tavo Aug 28 '17 at 09:53

3 Answers3

3

As it said from the javadoc

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

This means that your methods notify and wait should own monitor. Or in other words the object that is calling these method must be synchronized. Your this object is not synchronized. That's why you get this exception. Call this method from lock object in your case.

Your logic is still wrong but it is up to you to explore that.

Izbassar Tolegen
  • 1,990
  • 2
  • 20
  • 37
  • I have corrected and change the lock. I am able to print the odd & even number. I am not sure what do you mean by my logic is wrong.If there is something can you please point out. – crazyStart Aug 28 '17 at 10:18
  • 1
    by synchronizing on the whole method you don't getting desired concurent or parallel execution. that's make no sense in the whole idea of that. maybe you need some more intersting tasks. try to get the problems of that and how you can approach that and so on. It is not topic on the question though. – Izbassar Tolegen Aug 28 '17 at 10:22
  • totally agree with you. I am trying to learn multi threading so solving question which I found online, I am not able to find practice questions for the same. Thanks for the help. Cheers – crazyStart Aug 28 '17 at 10:36
3

You wait and notify on this, but you should wait and notify on lock because you synchronize on lock, you can't wait and notify on other object than the one on which you're synchronizing, working version:

class EVENODDimpl implements Runnable {
    int num;
    int temp = 0;
    Object lock = new Object();

    public EVENODDimpl( int num) {
        this.num = num;
    }

    public void run() {
        try {
            synchronized (lock) {
                while(temp<num) {
                    temp++;
                    System.out.println(Thread.currentThread().getName()+"   "+temp);
                    lock.notify();
                    lock.wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } 
    }
}
Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
1

java.lang.IllegalMonitorStateException Exception occur because you are using notify method on the object this.notify() but that Object is not synchronized. Replace synchronized (lock) with this: synchronized (this)

Nidhi257
  • 754
  • 1
  • 5
  • 23