Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Wait and Notify: IllegalMonitorStateException

I don't completely understand how wait and notify (of Object) work, and as a result I'm forced to slim down my attempts into the following section of code.

Main.java:

import java.util.ArrayList;  class Main {   public static Main main = null;    public static int numRunners = 4;   public static ArrayList<Runner> runners = null;    public static void main(String[] args)   {     main = new Main();   }    Main()   {     runners = new ArrayList<Runner>(numRunners);      for (int i = 0; i < numRunners; i++)     {       Runner r = new Runner();       runners.add(r);       new Thread(r).start();     }      System.out.println("Runners ready.");     notifyAll();   } } 

Runner.java:

class Runner implements Runnable {   public void run()   {     try     {       Main.main.wait();     } catch (InterruptedException e) {}     System.out.println("Runner away!");   } } 

Currently I get an IllegalMonitorStateException when calling Main.main.wait();, but I don't understand why. From what I can see, I need to synchronize Runner.run, but in doing so I assume it would only notify one thread, when the idea is to notify them all.

I've looked at java.util.concurrent, but I can't find a suitable replacement (maybe I'm just missing something).

like image 278
skeggse Avatar asked Aug 19 '11 19:08

skeggse


People also ask

How do I resolve Java Lang IllegalMonitorStateException?

The IllegalMonitorStateException can be resolved by calling the wait() , notify() and notifyAll() methods after acquiring an object lock, i.e. within a synchronized block or method.

How do you use wait and notify in Java?

The wait() Method Simply put, calling wait() forces the current thread to wait until some other thread invokes notify() or notifyAll() on the same object. For this, the current thread must own the object's monitor.

Which exception is thrown by Wait method?

The IllegalMonitorStateException is related to multithreading programming in Java. If we have a monitor we want to synchronize on, this exception is thrown to indicate that a thread tried to wait or to notify other threads waiting on that monitor, without owning it.

What is wait () in Java?

Simply put, wait() is an instance method that's used for thread synchronization. It can be called on any object, as it's defined right on java. lang. Object, but it can only be called from a synchronized block. It releases the lock on the object so that another thread can jump in and acquire a lock.


1 Answers

You can't wait() on an object unless the current thread owns that object's monitor. To do that, you must synchronize on it:

class Runner implements Runnable {   public void run()   {     try     {       synchronized(Main.main) {         Main.main.wait();       }     } catch (InterruptedException e) {}     System.out.println("Runner away!");   } } 

The same rule applies to notify()/notifyAll() as well.

The Javadocs for wait() mention this:

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

Throws:

IllegalMonitorStateException – if the current thread is not the owner of this object's monitor.

And from notify():

A thread becomes the owner of the object's monitor in one of three ways:

  • By executing a synchronized instance method of that object.
  • By executing the body of a synchronized statement that synchronizes on the object.
  • For objects of type Class, by executing a synchronized static method of that class.
like image 76
dlev Avatar answered Oct 05 '22 15:10

dlev