1

After execution the below code and throwing IllegalMonitorStateException exception. I am getting error as:

java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at com.blt.ThreadExample.main(ThreadExample.java:21)

I am new in multithreading, I want to use wait() and notify() in the code.

package com.blt;



public class ThreadExample implements Runnable {
    public static void main(String args[])
    {


        System.out.println("A");
        Thread T = new Thread(new ThreadExample());
        Thread T1 = new Thread(new ThreadExample());

        System.out.println("B");
        try
        {
        T.setName("thread 1");
        T.start();
        T1.setName("thread 2");
        System.out.println("C");
        T.notify();

        System.out.println("D");
        T1.start();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }


        public  void run()
{


            synchronized(ThreadExample.class)
            {


        for(int i=0; i<5; i++)
    {

        try
        {
            Thread.currentThread().wait(400);
         System.out.println("Inside run=>"+Thread.currentThread().getName());
         Thread.currentThread().sleep(2000);




        }
         catch(Exception e)
        {
            e.printStackTrace();
        }
      }  
}
}
}
Lukas Knuth
  • 25,449
  • 15
  • 83
  • 111
NullPointer
  • 152
  • 1
  • 16
  • actually, there have been very similar questions [here][1] before. [1]: http://stackoverflow.com/questions/7126550/java-wait-and-notify-illegalmonitorstateexception?rq=1 – Ralf H Feb 11 '13 at 12:29

3 Answers3

4

As explained in the javadoc, you need to be within a synchronized block using the object as a monitor to be able to call notify or wait on that object.

Thread.currentThread() is going to be difficult to track, so I suggest you used another object. For example:

public class ThreadExample implements Runnable {

    private static final Object lock = new Object();

    public static void main(String args[]) {
        System.out.println("A");
        Thread T = new Thread(new ThreadExample());
        Thread T1 = new Thread(new ThreadExample());

        System.out.println("B");
        try {
            T.setName("thread 1");
            T.start();
            T1.setName("thread 2");
            System.out.println("C");
            synchronized(lock) {
                lock.notify();
            }
            System.out.println("D");
            T1.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
        synchronized (lock) {
            for (int i = 0; i < 5; i++) {
                try {
                    lock.wait(400);
                    System.out.println("Inside run=>" + Thread.currentThread().getName());
                    Thread.currentThread().sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Note that there several other issues in your code, in particular:

  • you should always call wait in a loop (read the javadoc for more details)
  • sleep is a static method, no need to use Thread.currentThread().sleep(2000); - sleep(2000); will do the same.
assylias
  • 321,522
  • 82
  • 660
  • 783
  • I have used wait() inside synchorized block only. – NullPointer Feb 11 '13 at 12:27
  • @user1999444 multithreading is a difficult topic - you should read the documentation before using those methods as it can lead to weird results when used inappropriately. – assylias Feb 11 '13 at 12:31
  • Thankyou assylias!! from now onwards first i will go through Javadoc before trying any example in multithreading – NullPointer Feb 11 '13 at 12:42
  • @user1999444 A good place to start is the [Java tutorial on concurrency](http://docs.oracle.com/javase/tutorial/essential/concurrency/). – assylias Feb 11 '13 at 13:20
2

These methods have to be enclosed in a synchronized block. Read about object locks in java tutorial.

In other words:

//thread 1
synchronized (commonObj) {
  commonObj.wait();
}

//thread 2:
synchronized (commonObj) {
  commonObj.notify();
}

Same question: How to use wait and notify in Java?

Community
  • 1
  • 1
Dariusz
  • 21,561
  • 9
  • 74
  • 114
0

Try this.. and let me know if you have any doudt.

package com.blt;

public class ThreadExample implements Runnable {
    public static void main(String args[]) {
        Thread T1 = new Thread(new ThreadExample());
        Thread T2 = new Thread(new ThreadExample());
        try {
            T1.setName("thread 1");
            T1.start();
            T2.setName("thread 2");
            T2.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {

        synchronized (ThreadExample.class) {
            for (int i = 0; i < 5; i++) {
                try {
                    ThreadExample.class.notify();
                    System.out.println("Thread going to wait state::"+ Thread.currentThread().getName());
                    ThreadExample.class.wait(400);
                    System.out.println("Thread notified is::"+ Thread.currentThread().getName());
                    System.out.println("Thread going to sleep state::"+ Thread.currentThread().getName());
                    Thread.sleep(2000);
                    System.out.println("==========");

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
Rakesh Mahapatro
  • 866
  • 5
  • 12
  • @Antriksh You can only call `someObject.notify()` while holding the lock on `someObject`. In this example, the synchronized block uses `ThreadExample.class` as a lock, so `notify` can only be called on that object. – assylias Feb 11 '13 at 14:12