Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

notifyAll() throws IllegalMonitorStateException

I am designing two threads: one has to get the name of players, and the second thread has to wait for the name being set in order to continue, but notify() all in the first thread is throwing the IllegalMonitorStateException error.

private NameFecth nameFetch;
private UseName useName;
private Object nameSetLock; 
public static void method{
   nameSetLock = new Object()
   nameFetch = new NameFetch(nameSetLock);
   useName = new UseName(nameSetLock);
   Thread nameFetchThread = new Thread(nameFetch);
   nameFetchThread.start();
   Thread useNameThread = new Thread(useName);
   useNameThread.start();
}

public class NameFetch implements Runnable{
    /*variables and constructers*/

    public void run(){
       /*get name and set the variable somehow*/
       synchronized(nameSetLock){
         notifyAll();
       }
    }
}

public class UseName implements Runnable{
    /*variables and constructers*/

   public void run(){
     while(!nameBeenSet){
       synchronized(nameSetLock){
         try{
           wait();
         }catch(InterruptedException e) {}
       }
     }

}

What have I done wrong?

like image 234
Newyo Avatar asked Aug 13 '13 12:08

Newyo


People also ask

How do I fix 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.

What is Java Lang IllegalMonitorStateException?

java.lang.IllegalMonitorStateException. 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. See also: Object.

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 difference between notify and notifyAll?

Sr. No. In the case of the multiThreading, notify() method sends the notification to only one thread among the multiple waiting threads which are waiting for the send lock. While notifyAll() methods in the same context send notifications to all waiting threads instead of a single thread.


2 Answers

You're calling wait and notify without synchronizing on the thing you're waiting on or notifying. As documented in Object.notifyAll:

Throws:
IllegalMonitorStateException - if the current thread is not the owner of this object's monitor.

So this:

synchronized(nameSetLock){
  notifyAll();
}

should be:

synchronized(nameSetLock){
  nameSetLock.notifyAll();
}

... and ditto for wait. Note that your current code wouldn't even compile as you're using syncronized rather than synchronized, which suggests that you didn't post your actual code. It's possible that in typing out the code you've actually changed the problem - in which case you should edit your question to be more representative.

like image 82
Jon Skeet Avatar answered Oct 04 '22 22:10

Jon Skeet


It looks like your issue that you are using the lock incorectly. You synchronized block is on nameSetLock and you are calling your notifyall on your NameFetch object instance (which is the sayme a synchronized(this).

You should do nameSetLock.wait when you want to use the lock and nameSetLock.notifyAll to notify.

like image 20
joey.enfield Avatar answered Oct 04 '22 22:10

joey.enfield