0

I am trying two print two thread's name concurrently. Can any body suggest , what i am doing wrong? I am getting "IllegalMonitorStateException

//ODD THREAD RUNNABLE public class OddThread implements Runnable {

    MainClass obj;
    public OddThread(MainClass obj) {
        // TODO Auto-generated constructor stub
        this.obj= obj;
    }
    public void run() {
        int number=1;
        while(number <10)
        {
          obj.PrintNumbers();
          notifyAll();
          try {
            wait();
        } catch (InterruptedException e) {System.out.println("Exception in wait of OddThread");
        }
          number = number+2;

        }

    }

}

// Even THREAD RUNNABLE

public class EvenThread implements Runnable{

    MainClass obj;
    public EvenThread(MainClass obj)
    {
        this.obj=obj;
    }
    public void run() {
        int number=0;
        while(number<=10)
        {
          obj.PrintNumbers();
          notifyAll();
          try {
            wait();
        } catch (InterruptedException e) {
            System.out.println("Exception in wait of EvenThread");
        }
       number = number+2;
        }

    }

}

// MAIN CLASS

public class MainClass {
   public static void main(String[] args)
   {
       MainClass obj = new MainClass();
      // Boolean flag= true;
       EvenThread evenThread = new EvenThread(obj);
       OddThread oddThread = new OddThread(obj);
       Thread Even = new Thread(evenThread);
       Thread Odd = new Thread(oddThread);
       Even.setName("Even Thread");
       Odd.setName("Odd Thread");
       Even.start();
       Odd.start();
   }

   public synchronized void PrintNumbers()
   {
       System.out.println(Thread.currentThread().getName());
   }

}

The output i am getting is Even Thread Odd Thread Exception in thread "Even Thread" Exception in thread "Odd Thread" java.lang.IllegalMonitorStateException

user2991413
  • 521
  • 2
  • 9
  • 26
  • The default exception handler probably printed a _stack trace_ along with the name of the exception. The stack trace tells you exactly what your program was doing when the exception was thrown. Knowing what line of your program threw it, and reading the Javadoc for the method that you called on that line should tell you everything you need to know. – Solomon Slow Nov 10 '15 at 14:01

2 Answers2

2

you should surround the notifyAll() and wait() within synchronized (this) {} like:

synchronized (this) {
    notifyAll();
}

and

synchronized (this) {
    wait();
}

these method notify(),notifyAll(),wait() can only be called by a thread that is the owner of this object's monitor,so you must surround them in a synchronized block,as is said Here the Object Java doc

BlackJoker
  • 3,099
  • 2
  • 20
  • 27
  • Thanks for replying. The method PrintNumbers(), which is being called from run() of both the threads, is synchronized . So do i still need to add a synchronized block and then call wait and notify in it ? – user2991413 Nov 10 '15 at 08:01
  • synchronized on PrintNumbers() only surround this method,not the next call `notifyAll();` – BlackJoker Nov 10 '15 at 08:05
  • My Bad. I was being silly not noticing that after the call of printNumber() the thread will come out of the method and release the lock hence call of notifyAll() or wait() afterwards will always throw IllegalMonitorStateException. – user2991413 Nov 10 '15 at 11:02
0

Here is the correct code:

public class MainClass {
    public static int number=0;
   public static void main(String[] args)
   {
       MainClass obj = new MainClass();
      // Boolean flag= true;
       EvenThread evenThread = new EvenThread(obj);
       OddThread oddThread = new OddThread(obj);
       Thread Even = new Thread(evenThread);
       Thread Odd = new Thread(oddThread);
       Even.setName("Even Thread");
       Odd.setName("Odd Thread");
       Even.start();
       Odd.start();
   }

   public synchronized void PrintNumbers()
   {  
       while(number<20)
       {
           System.out.println(number+"---"+Thread.currentThread().getName());
           number++;
           notifyAll();

           try {
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

       }
   }

}




public class OddThread implements Runnable {


    MainClass obj;
    public OddThread(MainClass obj) {
        // TODO Auto-generated constructor stub
        this.obj= obj;
    }
    public void run() {

          obj.PrintNumbers();


    }

}



public class EvenThread implements Runnable{

    MainClass obj;
    public EvenThread(MainClass obj)
    {
        this.obj=obj;
    }
    public void run() {
        int number=0;

          obj.PrintNumbers();


    }

}
user2991413
  • 521
  • 2
  • 9
  • 26