なぜこれらは非常に基本的なものであり、すべてのオブジェクトがそれらを持たなければならず、それらを持つことでパフォーマンスが低下するのですか (おそらく何らかの状態がそれらに保存されます)。
tl;dr: これらはスレッド セーフなメソッドであり、その値に比べてコストが小さくなります。
これらの方法がサポートする基本的な現実は次のとおりです。
- Java は常にマルチスレッドです。例: jconsole または jvisualvm を使用して、プロセスによって使用されるスレッドのリストを確認します。
- 正確さは「パフォーマンス」よりも重要です。私がプロジェクトの採点をしていたとき (何年も前)、「間違った答えにすぐにたどり着くのはまだ間違っている」と説明しなければなりませんでした。
基本的に、これらのメソッドは、同期で使用されるオブジェクトごとのモニターを管理するためのいくつかのフックを提供します。具体的にはsynchronized(objectWithMonitor)
、特定のメソッドを持っている場合objectWithMonitor.wait()
、そのモニターを生成するために使用できます (たとえば、先に進む前に計算を完了するために別のメソッドが必要な場合)。その場合、ブロックされていた別の 1 つのメソッドが、そのモニターの進行を待機できるようになります。
一方、objectWithMonitor.notifyAll()
モニターを待機しているスレッドに、モニターをすぐに放棄することを知らせるために使用できます。ただし、同期ブロックを離れるまで、実際には先に進むことはできません。
モニタリング メカニズムでパフォーマンスやメモリ ヒットが発生する可能性がある特定の例 (たとえば、長い double のリスト) に関して、考慮すべき点がいくつかあります。
- まず、それを証明してください。マルチスレッドの正確性など、Java のコア メカニズムに大きな影響があると考える場合、その直感が間違っている可能性は十分にあります。最初に影響を測定します。それが深刻で、個々の Double で同期する必要がないことがわかっている場合は、代わりに double を使用することを検討してください。
- あなた、あなたの同僚、将来のメンテナンス コーダー (1 年後のあなた自身かもしれません) などが、あなたのデータへの細かい粒度のスレッド化されたアクセスを決して必要としないかどうか確信が持てない場合は、その可能性が非常に高くなります。これらのモニターを取り除くと、コードの柔軟性と保守性が低下するだけです。
オブジェクトごとと明示的な監視オブジェクトに関する質問に対するフォローアップ:
簡単な回答: @JonSkeet: はい、モニターを削除すると問題が発生します。摩擦が発生します。これらのモニターを維持すると、これが常にマルチスレッド システムObject
であることを思い出させてくれます。
組み込みのオブジェクト モニターは洗練されたものではありませんが、次の点に優れています。予測可能な方法で作業します。そしてその目的は明確です。 synchronized(this)
明確な意思表示です。初心者のコーダーに同時実行パッケージのみを使用するように強制すると、摩擦が発生します。そのパッケージには何が入っていますか?セマフォとは?フォークジョイン?
初心者のコーダーは、オブジェクト モニターを使用して適切なモデル ビュー コントローラー コードを作成できます。 synchronized
でwait
あり、notifyAll
素朴な (シンプルでアクセスしやすいが、おそらく最先端のパフォーマンスではないという意味で) スレッドセーフを実装するために使用できます。標準的な例は、AWTスレッドが値を取得してJLabelに配置する間に、1つのスレッドに値を設定させることができるこれらのDoubleの1つです(OPによって提示されます)。その場合、外部モニターを持つためだけに明示的な追加オブジェクトを作成する正当な理由はありません。
やや複雑なレベルでは、これらの同じ方法が外部監視方法として役立ちます。上記の例では、明示的にそれを行いました (上記の objectWithMonitor フラグメントを参照)。繰り返しになりますが、これらのメソッドは、比較的単純なスレッド セーフをまとめるのに非常に便利です。
さらに高度になりたい場合は、 Java Concurrency In Practiceを読むことを真剣に検討する必要があると思います(まだ読んでいない場合)。読み取りロックと書き込みロックは非常に強力であり、複雑さを増しすぎることはありません。
パンチライン:基本的な同期方法を使用すると、スレッド セーフを備えた最新のマルチコア プロセッサによって実現されるパフォーマンスの大部分を、多くのオーバーヘッドなしで活用できます。