notifyAll()抛出IllegalMonitorStateException
我正在设计两个线程:一个必须得到播放器的名称,第二个线程必须等待设置的名称才能继续,但第一个线程中的notify()all抛出了IllegalMonitorStateException错误。
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) {} } } }
我做错了什么?
您正在呼叫wait
并notify
没有同步您正在等待或通知的事情。 如Object.notifyAll
:
抛出:
IllegalMonitorStateException
– 如果当前线程不是此对象的监视器的所有者。
所以这:
synchronized(nameSetLock){ notifyAll(); }
应该:
synchronized(nameSetLock){ nameSetLock.notifyAll(); }
……同样wait
。 请注意,您当前的代码甚至不会编译,因为您使用的是syncronized
而不是synchronized
,这表示您没有发布实际代码。 在键入代码时,您实际上可能已经改变了问题 – 在这种情况下,您应该编辑您的问题以使其更具代表性。
看起来你的问题是你正在使用锁。 您在nameSetLock上使用了synchronized块,并且在NameFetch对象实例上调用了notifyall(这是一个同步的(这个)。
如果要使用lock和nameSetLock.notifyAll进行通知,则应该执行nameSetLock.wait。
来自IllegalStateException
的JavaDoc
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建议它会起作用。
当我忘记在方法调用中添加synchronized时,就会发生这种情况。