如何处理java线程

时间:2009-04-21 20:54:49

标签: java multithreading

我有一个叫做沟通者的班级。此类是从另一个程序接收事件的线程的侦听器。此类还有一个方法调用刷新,它向程序发送和操作,等待通过侦听器的响应。

两种方法属于同一类,但由不同的线程调用。

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)
        ...

“等待”另一个线程完成的正确方法是什么。感谢。

5 个答案:

答案 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,它实现CollectionQueueBlockingQueue执行等待和通知的所有工作。您的线程只能调用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;
}