5

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?

4

4 回答 4

16

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.

于 2013-08-13T12:52:23.607 回答
1

看起来您的问题是您错误地使用了锁。您的同步块位于 nameSetLock 上,并且您正在 NameFetch 对象实例上调用您的 notifyall(这就是说的同步(this)。

当你想使用锁和 nameSetLock.notifyAll 通知时,你应该做 nameSetLock.wait。

于 2013-08-13T12:51:11.710 回答
1

来自 JavaDocIllegalStateException

  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. 

您正在尝试在没有该对象锁定的情况下调用 wait() 和 notifyAll()。

请尝试@Jon 建议的方法。

于 2013-08-13T12:57:07.840 回答
0

当我忘记在方法调用中添加同步时,就会发生这种情况。

于 2016-04-14T08:23:22.247 回答