2012-02-14 12 views
5

これは私にとって本当に奇妙ですが、私のプログラムでnotifyAll()/ notify()が失敗したようです。 コードはかなり複雑です。基本的に私は3つのスレッドA、B、Cを持っています。Java - notifyAll()とnotify()は失敗しましたか?出来ますか?

AはBに要求を送り、10秒のタイムアウトで要求をwait()し、Bが終了すると、

デッドループのCが、キューにAの文字列を多く送り、Aがそれをピックアップして出力します。 Aが文字列を出力するたびに、Bに要求を送信して待ちます。

ので、ワークフローが可能になる:

Cはdeadloopで

  1. AはC
  2. A Bにリクエストを送信し、待つ(10)
  3. から文字列を出力を供給し続けますB notify()A ......

  4. Aは、C から文字列を出力します。何度も何度も....

これは数秒で動作します。しかし、しばらくすると、Bがいつnotify()Aを持っているかが表示されます.CがAを供給するために使用するキューが急速に増加し、文字列がAで印刷されないため、Aはまだ待機しています。 、Aは要求のタイムアウトに苦情を言います。

これは、notify()を呼び出した後にBがメッセージを出力したため、notify()が失敗したようです。与えられた待機/通知はJavaの根本的な機能ですが、私はそれが失敗するとは信じられません。出来ますか?

+8

あなたは確かですか?Aは「まだ待っていますか?もう1つの可能性は、通知の後に* waiting *を開始したことで、これはコードが壊れてしまうことです。 (あなたはすでに起こったことを待つべきではありません。) –

+0

たぶんBは、電話を待つ前に通知するといいますか? –

+1

私たちはコードをお願いします。 – vulkanino

答えて

2

notify()は、その時点でスレッドwait()がある場合にのみ機能します。

使用するイディオムは、notify()/ notifyAll()と同じ同期ブロック内の状態を変更することです。待機ブロックでは、状態の変更を繰り返し確認します。通知が早過ぎると、それを記録する状態が変わります。また、待機が偽って起きた場合は、状態が変更されていない場合は再び待機します。

public synchronized void notifyReady() { 
    ready = true; 
    notifyAll(); 
} 

public synchronized void waitForReady() throws InterruptedException { 
    while(!ready) 
     wait(); 
} 
+0

おかげでみんな。タイミングの問題が原因であることが判明しました –

関連する問題