2009-04-21 175 views
1

我有一個叫communicator的類。該類是接收來自另一個程序的事件的線程的偵聽器。這個類還有一個方法調用刷新,它發送和執行程序a等待通過偵聽器來的響應。如何處理java線程

兩種方法都在同一個類中,但是由不同的線程調用。

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

什麼是正確的方法「等」另一個線程來完成。謝謝。

回答

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; 
     } 
} 
+0

要明確,「任何線程」的意思是「任何一個等待線程」,而不是「所有等待線程」。 – erickson 2009-04-21 21:08:19

0

Object.wait()的JavaDoc中: ‘當前線程必須擁有該對象的監視器。’ 所以你需要在你要調用的對象上進行同步。

或者,您可以使用BlockingQueue,它實現了CollectionQueueBlockingQueue做所有的等待和通知的工作。你的線程可以調用take(),這將阻塞,直到數據可用。您可以使用各種插入方法(添加,放入等)將數據添加到隊列中。順便說一句,插入方法調用notify,而take()調用wait

1

方法wait()notify()只能從其實例上當前同步的線程中調用。

宣佈「processRefreshEvent」​​,或者更好的是,就在的代碼塊來修改所使用由refresh方法的狀態下,與notify()呼叫在一起。

public void processRefreshEvent(ManagerEvent event){ 
    // processing event 
    synchronized (this) { 
    // modify shared state with results of processing. 
    notify(); 
    } 
} 
0

請仔細閱讀java.lang.Object.wait()notify()的Javadoc。

您應該同步的等待()與適當的顯示器,在這種情況下:

try{ 
    synchronized(this){ 
      wait(5000); 
    } 
} 
catch (InterruptedException e) { 
} finally{ 
      isRefreshing = false; 
} 
1

你說你要等到另一個線程完成?然後,只需在要等待的Thread對象上調用join()。