2

多くの調査の結果、私は JMM を非常によく理解していると思います。オブジェクトが 2 つのスレッド間で共有されている場合、同じモニターですべてのアクセスを同期する必要があることを十分に理解しています。複数のアクティブなスレッドがオブジェクトに同時にアクセスする場合、それらが何を観察するかについてすべての賭けがオフになることを理解しています。

ただし、オブジェクトを使用する他のスレッドが開始される (またはそのスレッドが構築される) 前に、オブジェクトが決定論的かつ実際に構築される場合、JMM は、後のスレッドによって表示されるオブジェクトの内容が、によって構成されたものと同じであることを保証しますか?以前のセットアップ スレッド。

IOW、スレッドで初めてオブジェクトを参照し、オブジェクトの実際の内容ではなく、CPU キャッシュなどによるダーティ メモリを観察することは可能ですか? それとも、JMM は、特定のオブジェクトへの参照を最初に取得するときに、それが参照するメモリが一貫していることを保証しますか?

私がまだ確信が持てない多くの場所で使用する特定のパターンが 1 つあるため、質問します。多くの場合、断片的な方法で構築および構成され、その後不変に使用されるオブジェクトがあります。これは断片的に構成されているため、そのメンバーを最終的なものにすることはできません (必要がない限り、これらすべてをビルダー パターンに変更したくありません)。

たとえば、HTTP 接続ハンドラを作成し、プラグイン オブジェクトを追加して特定の HTTP リクエストを処理します。ハンドラーはミューテーターを使用して作成および構成され、スレッドプールを使用して接続を処理する TCP 接続プロセッサーにインストールされます。接続ハンドラは、接続プロセッサのスレッド プールが開始される前に構成およびインストールされ、一度接続プロセッサにインストールされると決して変更されないため、すべてを設定するスレッドと接続を処理するスレッドとの間で明示的な同期を使用しません。

この特定のケースでは、スレッド構成もスレッドプールを開始する同じスレッドである可能性が高く、スレッドプールの開始が同期されるため、それを実行するすべてのスレッドも同じスレッドプールオブジェクトで同期されるため、これ根本的な問題を隠す可能性があります (私の API では、開始スレッドが構成スレッドと同じである必要はありません)。

4

2 に答える 2

2

通常、スレッドが相互作用するときは、事前発生関係が必要です。たとえば、同時キューによって提供されます。より細かい同期が必ずしも必要というわけではありません。

発生する前の関係なしにスレッド間でオブジェクトを渡すまれなケースは、安全でないパブリケーションとして知られています。finalこれを安全にするためのフィールドの使用に関するルールがあります。ただし、それに頼りたいと思うことはめったにありません。

スレッドでの呼び出しとスレッドの実行の間には、常に事前発生の関係があります。startそのため、オブジェクトが開始前に開始スレッドに安全に公開されている場合、開始されたスレッドもオブジェクトを一貫して認識します。

于 2009-11-05T21:47:37.827 に答える