2009-04-21 16 views
1

コミュニケータと呼ばれるクラスがあります。このクラスは、別のプログラムからイベントを受け取るスレッドのリスナーです。また、このクラスはメソッド呼び出しをリフレッシュして、プログラムにリスナー経由の応答を待ってアクションを送信します。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; 
    } 
} 

I上記のコードを実行する次の例外を取得:

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

+0

待機中のスレッドは、それ自身の目覚めを起こすことがあります。 –

0

Object.wait()さんのJavaDocから: 『現在のスレッドがこのオブジェクトのモニターを所有する必要があります。』 待機しているオブジェクトで同期する必要があります。

BlockingQueueを使用することもできます。これは、CollectionQueueを実装しています。 BlockingQueueすべての作業を待って通知します。あなたのスレッドはtake()に電話するだけで、データが利用できるようになるまでブロックされます。さまざまな挿入メソッド(add、putなど)を使用してキューにデータを追加します。挿入メソッドはnotifyを呼び出し、take()waitを呼び出します。

1

メソッドwait()notify()は、インスタンス上で現在同期されているスレッドからのみ呼び出すことができます。一緒にnotify()コールで、refresh方法で使用されている状態を変更

宣言「processRefreshEvent」​​、またはコードのいっそ、ちょうどブロック。

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()を呼び出します。

関連する問題