pra*_*ani 156 java multithreading wait
我在我的程序中使用java中的多线程.我已成功运行线程,但在我使用时Thread.wait()
,它正在抛出java.lang.IllegalMonitorStateException
.我怎样才能使线程等到通知为止?
Tom*_*ine 52
wait
定义在Object
,而不是它Thread
.监视器Thread
有点不可预测.
虽然所有Java对象都有监视器,但通常最好有一个专用锁:
private final Object lock = new Object();
Run Code Online (Sandbox Code Playgroud)
通过使用命名类,您可以以较小的内存成本(每个进程大约2K)轻松读取诊断信息:
private static final class Lock { }
private final Object lock = new Lock();
Run Code Online (Sandbox Code Playgroud)
为了wait
或notify
/ notifyAll
对象,您需要使用synchronized
语句持有锁.此外,您将需要一个while
循环来检查唤醒条件(在线程上找到一个好文本来解释原因).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
Run Code Online (Sandbox Code Playgroud)
通知:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Run Code Online (Sandbox Code Playgroud)
在进入多线程时,了解Java语言和java.util.concurrent.locks
锁(和java.util.concurrent.atomic
)是非常值得的.但是java.util.concurrent
尽可能使用数据结构.
小智 24
我知道这个帖子差不多2年了,但仍然需要关闭它,因为我也遇到了同样问题的Q/A会话......
请一遍又一遍地阅读illegalMonitorException的这个定义......
抛出IllegalMonitorException以指示线程已尝试在对象的监视器上等待,或者在没有指定监视器的情况下通知在对象监视器上等待的其他线程.
这一行一次又一次地说,当出现2种情况之一时,IllegalMonitorException就会出现....
1>在没有指定监视器的情况下等待对象的监视器.
2>通知在对象监视器上等待的其他线程,而不拥有指定的监视器.
有些人可能得到了他们的答案......谁都没有,那么请检查2个陈述....
同步(对象)
的Object.wait()
如果两个对象都相同...则不会发生illegalMonitorException.
现在再次阅读IllegalMonitorException定义,你不会再忘记它了...
根据您的评论,听起来您正在做这样的事情:
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
Run Code Online (Sandbox Code Playgroud)
有三个问题.
正如其他人所说,obj.wait()
只有在当前线程持有原始锁/互斥锁时才能调用obj
.如果当前线程没有锁定,则会看到您看到的异常.
这个thread.wait()
电话没有做你似乎期待它做的事情.具体来说,thread.wait()
不会导致指定的线程等待.而是它导致当前线程等到其他线程调用thread.notify()
或thread.notifyAll()
.
实际上没有安全的方法来强制Thread
实例暂停,如果它不想要.(Java对此最近的是不推荐使用的Thread.suspend()
方法,但该方法本质上是不安全的,如Javadoc中所述.)
如果您希望新开始Thread
暂停,最好的方法是创建一个CountdownLatch
实例并await()
在锁存器上调用线程来暂停.然后主线程将调用countDown()
锁存器以使暂停的线程继续.
与前面的点正交,使用Thread
对象作为锁/互斥锁可能会导致问题.例如,javadoc Thread::join
表示:
此实现使用一系列
this.wait
调用条件this.isAlive
.当一个线程终止时,该this.notifyAll
方法被调用.建议应用程序无法使用wait
,notify
或notifyAll
在Thread
实例.