2016-09-11 7 views
-2

オブジェクトに所有権を持たずにwait()メソッドを呼び出すと、例外が発生することがわかりました。 とJavaドキュメントから、別のスレッド *はどちらか、彼0​​方法や の呼び出しによって* を覚ますために、このオブジェクトのモニターで待機中のスレッドに通知するまで*スレッド このモニタと待機のリリースの所有権をwait() を呼び出すに* {@code notifyAll}方法。 したがって、wait()がオブジェクトに対して呼び出されると、その特定のスレッドは、他のスレッドがそれを通知するまで、そのオブジェクトのオブジェクトの所有権を失います。wait()を複数回呼び出しても例外がスローされないのはなぜですか?

wait()を何も通知せずに2回呼び出してもエラーが表示されないのはなぜですか? 私はちょうどプロデューサーを実行したので、他のスレッドはそれを知らせるためにそこにいないので、wait()メソッドは無限と呼ばれます。 最初のwait()コールの後で所有権が失われても、後続の待機コールでexceptions.isn'tがスローされるはずですが、なぜうまくいきますか?

class Producer extends Thread { 

    private Queue<Integer> queue; 
    private int maxSize; 

    public Producer(Queue<Integer> queue, int maxSize, String name) { 
     super(name); 
     this.queue = queue; 
     this.maxSize = maxSize; 
    } 

    public void run() { 
     while (true) { 
      synchronized (queue) { 
       try { 
        queue.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 

    } 
} 
+0

「複数回」とは何を意味しますか?上の 'run()'メソッドを別のスレッドから呼び出すのですか? (あなたが私たちに示していないコードから呼び出されているかもしれません) – markspace

答えて

3

このスレッドのみを実行すると、待機後にブロックされます(デバッグ出力を追加してみてください)。

wait()は、通知されるまでブロックし、戻す前にロックを再取得します。つまり、例の中でwait()が返された場合、再びqueueがロックされています。

編集:質問

の更新あたりはこのように、「通知することなく、二回wait()を呼び出すと、」通知されるまでwait()への最初の呼び出しがスレッドをブロックしますと、ことはできません。ループ内で無限に呼び出すことはできません。ブロックするか例外をスローします。

追加:ところで

(例えば、プロデューサまたはコンシューマ)をウェイクアップされた待機スレッドの保証がないよう、「裸」のウェイトを持つことは、しばしば危険です。 共通イディオム(Javaは、「内蔵のモニター」として - 条件変数を持っていない -​​ブロック)、おそらく消費者のために、この場合、

while(! condition) 
    wait(); 

のようなもので、

while(queue.isEmpty()) 
    wait(); 
のようなもの
+0

これがあなたの質問に答えるなら、あなたはここでループしていません。あなたは 'wait()'を一度呼び出してからコードが停止します。例外がスローされます。 – markspace

+0

@ markspace、はい、これが私の疑念を明らかにしました。ありがとう –

+0

@Sriharsha、あなたの質問に答えたら答えを受け入れてください。そうでない場合は、明確にしてください。私は答えを更新しようとします。 – drRobertz

関連する問題