2009-11-20 9 views

答えて

41

特定のオブジェクト(またはそのモニタ)がこの機能を使用するのを待つためです。

これらの方法の仕組みに間違いがあると思います。それらは単純にスレッド粒度レベルではなく、つまりではなく、wait()を呼び出す場合、notify()に次の呼び出しで呼び起こされた場合です。むしろ、特定のオブジェクトに対して常にwait()を呼び出すと、のnotifyへの呼び出しによってのみ呼び出されます。

これは、そうしなければ並行処理プリミティブがスケールされないためです。プログラム内のどこでもnotify()への呼び出しがwait()呼び出しでブロックされているスレッドを目覚めさせるので、の同時コードを混乱させる可能性があるため、グローバルな名前空間を持つことと同等です。したがって、特定のオブジェクトに対してそれらを呼び出す理由。それはwait-notifyペアが動作するためのコンテキストを提供するので、プライベートオブジェクトのmyBlockingObject.notify()を呼び出すと、クラス内のwaitメソッドを呼び出すスレッドのみを起床させることができます。別のオブジェクトで待機しているSpringスレッドの一部は、この呼び出しによって呼び起こされず、その逆もあります。

編集:それとも別の観点から、それに対処する - 私はあなたが待っているスレッドへのハンドルを取得し、それをウェイクアップするそのスレッドnotify()を呼ぶだろうと思ったあなたの質問から期待しています。それがこのように行われていない理由は、自分で家事をやる必要があるということです。待機するスレッドは、他のスレッドがそれを見ることができるどこかの参照を公開する必要があります。整合性と可視性を実現するためには、これを適切に同期させる必要があります。そしてスレッドを起こしたいときは、この参照を取得して目を覚まし、それをどこから読み込んでも削除する必要があります。手作業の足場がはるかに多く、眠っているスレッドでmyObj.wait()を呼び出してからwakerスレッドでmyObj.notify()を呼び出すのと比べて(特に並行環境では)間違ってしまう機会が増えています。

+7

これは、なぜANYオブジェクトを待つことができるのか答え始めません。なぜ特定のロッククラスやタイプがなかったのですか?またはマーカーインターフェイスですか? – mjaggard

+0

"... wait()呼び出しでブロックされているスレッドを起動させるため、並行コードを混乱させる可能性があります...それは、条件1が真になるまでループ内でwait()が呼び出されるため、実際に何かが壊れてはならないということです。 –

8

一度に1つのスレッドしかオブジェクトのモニタを所有できないため、このモニタはスレッドが待機しているか通知しているためです。 Object.notify()Object.wait()javadocを読んだ場合は、詳しく説明しています。

+0

こんにちはありがとうございました。テーラー – Bhupi

+0

よろしくお願いいたします。 –

10

もっとも単純で明白な理由は、すべてのオブジェクト(単なるスレッドではない) がスレッドのモニタになる可能性があるということです。待機および通知は、 モニタで呼び出されます。実行中のスレッドは、モニターと照合します。 waitメソッドとnotifyメソッドはObjectで、スレッドではありません。

0

Read hereは、待機と通知の説明です。

しかし、アプリケーションでこれらを避けて、より新しいjava.util.concurrentパッケージを使用する方がよいでしょう。

1

同期のメカニズムには、オブジェクトの概念モニタが関係します。 wait()が呼び出されると、モニタが要求され、モニタが取得されるか、InterruptedExceptionが発生するまで、さらに実行が中断されます。 notify()が呼び出されると、モニターは解放されます。

wait()とnotify()がObjectクラスではなくThreadクラスに配置されている場合を考えてみましょう。コードのある時点でcurrentThread.wait()が呼び出され、次にオブジェクトanObjectがアクセスされます。

//......... 
currentThread.wait(); 
anObject.setValue(1); 
//......... 

currentThread.wait()が呼び出されると、currentThreadのモニターが要求され、モニタが取得又はInterruptedExceptionあるが発生されるかまで、さらなる実行が行われません。待ち状態で他のオブジェクトから別のオブジェクトanotherObjectのメソッドfoo()が別のスレッドから呼び出された場合は、呼び出されたメソッドfoo()anObjectにアクセスしなくてもスタックされます。最初のwait()メソッドがスレッド自体の代わりにanObjectで呼び出された場合、同じスレッドに存在するオブジェクト上の他のメソッド呼び出し(anObjectにアクセスしない)はスタックしません。

したがって、オブジェクトクラス(またはそのサブクラス)のwait()およびnotify()メソッドを呼び出すと、並行性が向上し、これらのメソッドがThreadクラスではなくObjectクラスに含まれます。

0

私は簡単な方法でそれを置く:

はwait()を呼び出すか、オブジェクトのモニターを所有する必要があります)(通知すること - これは、同期中に存在する必要があります)((待つ)、または通知意味しますこれらのメソッドはオブジェクトクラスに存在する理由厥

synchronized(monitorObj){ 
monitorObj.wait() or even notify 
} 

ブロック

0

これは、これらの方法は、インタースレッド通信とinterthreadcommunicationためのものであるからであるロックを使用することによって発生し、それはロックがobjects.henceに関連付けられていますオブジェクトクラス内。

0

待機と通知メソッドは、Javaの2つのスレッド間の通信に使用されます。したがって、Objectクラスは、Javaのすべてのオブジェクトで使用できるようにするための正しい場所です。

もう1つの理由は、ロックはオブジェクト単位で利用できるということです。スレッドはロックを必要とし、ロックを待つか、どのスレッドがロックを保持しているか分からず、ロックがあるスレッドによって保持されていることを知っているため、同期されたブロック内のスレッドを知り、ロック

1

その他の回答の中には、「モニタ」という言葉が使われていますが、その意味を説明するものはありません。

"monitor"という名前は1970年代に作られたもので、独自の固有のロックを持ち、関連付けられた待機/通知メカニズムを持つオブジェクトを参照していました。 https://en.wikipedia.org/wiki/Monitor_%28synchronization%29

20年後、デスクトップとマルチプロセッサのコンピュータが新しくなった瞬間がありました。ソフトウェアを設計する正しい方法は、オブジェクト指向のプログラムを作成することだと考えるのが流行っていました。 which すべてのオブジェクトはモニターでした。

このような便利なアイデアは出ていませんが、Javaプログラミング言語が発明されたときはまさにその瞬間です。

関連する問題