我有一个叫做沟通者的班级。此类是从另一个程序接收事件的线程的侦听器。此类还有一个方法调用刷新,它向程序发送和操作,等待通过侦听器的响应。
两种方法属于同一类,但由不同的线程调用。
public void processRefreshEvent(ManagerEvent event){
//processing event
//...
//I'm done
notify();
}
public synchronized void refresh() throws Exception {
isRefreshing = true;
try {
manager.send(new refresh());
} catch (ManagerException e) {
isRefreshing = false;
}
try {
wait(5000);
} catch (InterruptedException e) {
} finally{
isRefreshing = false;
}
}
执行上面的代码时,我得到以下异常:
java.lang.IllegalMonitorStateException: current thread not owner at java.lang.Object.wait(Native Method) at Communicator.refresh(Communicator.java:203) ...
“等待”另一个线程完成的正确方法是什么。感谢。
答案 0 :(得分:2)
您需要在监视器上同步线程。例如(使用当前对象作为监视器):
public void processRefreshEvent(ManagerEvent event){
//processing event
//...
//I'm done
synchronized(this) {
notify(); // you are basically notifying any thread who has blocked
// on this monitor - in our case, the instance of this object
}
}
public synchronized void refresh() throws Exception {
isRefreshing = true;
try {
manager.send(new refresh());
} catch (ManagerException e) {
isRefreshing = false;
}
try {
synchronized(this) {
wait(5000); // wait will give up the monitor
}
} catch (InterruptedException e) {
} finally{
isRefreshing = false;
}
}
答案 1 :(得分:1)
方法wait()
和notify()
只能从当前在其实例上同步的线程调用。
声明“processRefreshEvent”synchronized
,或者更好的是,只是修改refresh
方法使用的状态的代码块,以及notify()
调用。
public void processRefreshEvent(ManagerEvent event){
// processing event
synchronized (this) {
// modify shared state with results of processing.
notify();
}
}
答案 2 :(得分:1)
你说你想等到另一个线程完成?然后在你想要等待的Thread对象上调用join()。
答案 3 :(得分:0)
来自Object.wait()
的JavaDocs:
“当前线程必须拥有此对象的监视器。”
因此,您需要同步您正在调用的对象等待。
或者,您可以使用BlockingQueue
,它实现Collection
和Queue
。 BlockingQueue
执行等待和通知的所有工作。您的线程只能调用take()
,它将阻塞直到数据可用。您可以使用各种插入方法(add,put等)将数据添加到队列中。 BTW插入方法在notify
调用take()
时调用wait
。
答案 4 :(得分:0)
请阅读java.lang.Object.wait()和notify()上的JavaDoc。
您应该将wait()与适当的监视器同步,在这种情况下:
try{
synchronized(this){
wait(5000);
}
}
catch (InterruptedException e) {
} finally{
isRefreshing = false;
}