クラスではなく、およびnotify()
メソッドがObject
クラスで宣言されているのはなぜですか?JavaのObjectクラスでwait()とnotify()が宣言されているのはなぜですか?
答えて
特定のオブジェクト(またはそのモニタ)がこの機能を使用するのを待つためです。
これらの方法の仕組みに間違いがあると思います。それらは単純にスレッド粒度レベルではなく、つまりではなく、wait()
を呼び出す場合、notify()
に次の呼び出しで呼び起こされた場合です。むしろ、特定のオブジェクトに対して常にwait()
を呼び出すと、のnotify
への呼び出しによってのみ呼び出されます。
これは、そうしなければ並行処理プリミティブがスケールされないためです。プログラム内のどこでもnotify()
への呼び出しがwait()
呼び出しでブロックされているスレッドを目覚めさせるので、の同時コードを混乱させる可能性があるため、グローバルな名前空間を持つことと同等です。したがって、特定のオブジェクトに対してそれらを呼び出す理由。それはwait-notifyペアが動作するためのコンテキストを提供するので、プライベートオブジェクトのmyBlockingObject.notify()
を呼び出すと、クラス内のwaitメソッドを呼び出すスレッドのみを起床させることができます。別のオブジェクトで待機しているSpringスレッドの一部は、この呼び出しによって呼び起こされず、その逆もあります。
編集:それとも別の観点から、それに対処する - 私はあなたが待っているスレッドへのハンドルを取得し、それをウェイクアップするそのスレッドにnotify()
を呼ぶだろうと思ったあなたの質問から期待しています。それがこのように行われていない理由は、自分で家事をやる必要があるということです。待機するスレッドは、他のスレッドがそれを見ることができるどこかの参照を公開する必要があります。整合性と可視性を実現するためには、これを適切に同期させる必要があります。そしてスレッドを起こしたいときは、この参照を取得して目を覚まし、それをどこから読み込んでも削除する必要があります。手作業の足場がはるかに多く、眠っているスレッドでmyObj.wait()
を呼び出してからwakerスレッドでmyObj.notify()
を呼び出すのと比べて(特に並行環境では)間違ってしまう機会が増えています。
もっとも単純で明白な理由は、すべてのオブジェクト(単なるスレッドではない) がスレッドのモニタになる可能性があるということです。待機および通知は、 モニタで呼び出されます。実行中のスレッドは、モニターと照合します。 waitメソッドとnotifyメソッドはObjectで、スレッドではありません。
Read hereは、待機と通知の説明です。
しかし、アプリケーションでこれらを避けて、より新しいjava.util.concurrentパッケージを使用する方がよいでしょう。
同期のメカニズムには、オブジェクトの概念モニタが関係します。 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クラスに含まれます。
私は簡単な方法でそれを置く:
はwait()を呼び出すか、オブジェクトのモニターを所有する必要があります)(通知すること - これは、同期中に存在する必要があります)((待つ)、または通知意味しますこれらのメソッドはオブジェクトクラスに存在する理由厥
synchronized(monitorObj){
monitorObj.wait() or even notify
}
ブロック
これは、これらの方法は、インタースレッド通信とinterthreadcommunicationためのものであるからであるロックを使用することによって発生し、それはロックがobjects.henceに関連付けられていますオブジェクトクラス内。
待機と通知メソッドは、Javaの2つのスレッド間の通信に使用されます。したがって、Objectクラスは、Javaのすべてのオブジェクトで使用できるようにするための正しい場所です。
もう1つの理由は、ロックはオブジェクト単位で利用できるということです。スレッドはロックを必要とし、ロックを待つか、どのスレッドがロックを保持しているか分からず、ロックがあるスレッドによって保持されていることを知っているため、同期されたブロック内のスレッドを知り、ロック
その他の回答の中には、「モニタ」という言葉が使われていますが、その意味を説明するものはありません。
"monitor"という名前は1970年代に作られたもので、独自の固有のロックを持ち、関連付けられた待機/通知メカニズムを持つオブジェクトを参照していました。 https://en.wikipedia.org/wiki/Monitor_%28synchronization%29
20年後、デスクトップとマルチプロセッサのコンピュータが新しくなった瞬間がありました。ソフトウェアを設計する正しい方法は、オブジェクト指向のプログラムを作成することだと考えるのが流行っていました。 which すべてのオブジェクトはモニターでした。
このような便利なアイデアは出ていませんが、Javaプログラミング言語が発明されたときはまさにその瞬間です。
- 1. なぜ、wait、notifyおよびnotifyAllはCloneableのようなObjectクラスのメソッドです
- 2. なぜwait()とnotify()が特別なクラスに含まれていないのですか?
- 3. Javaでクラスが静的であると宣言されているのはなぜですか?
- 4. Javaで別のファイルで宣言されているのはなぜですか?
- 5. なぜGADBannerViewが宣言されていないのですか?
- 6. なぜ 'EINTR'が宣言されていないのですか?
- 7. HttpServletクラスが抽象クラスとして宣言されているのはなぜですか?
- 8. wait()の前にJavaのnotify()が呼び出される
- 9. wait-notifyとCountDownLatchの違い
- 10. Subclass型の宣言が、SuperクラスのObjectを参照できないのはなぜですか?
- 11. マップとしてクラス名を宣言できないのはなぜですか?
- 12. Javaでマルチスレッド環境用のカスタムイベントリスナーWait()とnotify()を使用する
- 13. aspxコードビハインドファイルが部分クラスとして宣言されているのはなぜですか?
- 14. なぜclangは_Imaginary_Iが宣言されていないのですか?
- 15. `std`モジュールが宣言されていないのはなぜですか?
- 16. 同じクラスでメソッドが定義されていると、宣言されていない識別子 'downloadDataFromURL'が使用されるのはなぜですか?
- 17. なぜ、wait、notifyおよびnotifyAllメソッドがオブジェクトクラスにあるのですか?
- 18. C++エラーはクラスが宣言されていないと言っています
- 19. argv []がconstとして宣言されているのはなぜですか? ARGV [] CONSTとして宣言された理由のObjective-Cでは、
- 20. JDKクラスで、Serializableが完全修飾名で宣言されているのはなぜですか?
- 21. なぜこの変数が宣言されていないのですか?
- 22. なぜこのエラー 'init_task'が宣言されていないのですか?
- 23. Javaでwait()とnotify()を使用してブロックしました
- 24. @SpringBootApplicationクラスで宣言されたBeanがステレオタイプのクラスではないのに登録されているのはなぜですか?
- 25. PrintStreamクラスの参照がjavaのSystemクラスの静的変数として宣言されているのはなぜですか?
- 26. Javaの次のコードでwait()とnotify()の何が問題になっていますか?
- 27. 私のクラスが内部で宣言されたインタフェースを実装できないのはなぜですか?
- 28. クラスの前方宣言とクラスの宣言の違いは何ですか?
- 29. プロトタイプで宣言されている関数が呼び出されないのはなぜですか?
- 30. なぜクラス全体をJavaで同期として宣言できないのですか?
これは、なぜANYオブジェクトを待つことができるのか答え始めません。なぜ特定のロッククラスやタイプがなかったのですか?またはマーカーインターフェイスですか? – mjaggard
"... wait()呼び出しでブロックされているスレッドを起動させるため、並行コードを混乱させる可能性があります...それは、条件1が真になるまでループ内でwait()が呼び出されるため、実際に何かが壊れてはならないということです。 –