変数を揮発性にするか、両方のスレッドを何かで同期させることにより、1つのスレッドが変数に加えた変更を他のスレッドで確実に確認できます。変更されるものがjava.util.ConcurrentHashMapである場合、このマップを保持している変数のタイプを揮発性として宣言することによってメモリバリアを作成することは理にかなっていますか、またはマップにアクセスするリーダーは(たとえばを介してmyMap.values()
)最新のものを取得しますとにかく可能なビュー?コンテキストとして、ロックフリーの読み取りソリューションをConcurrentHashMapに切り替える、読み取りが多く、書き込みが軽いシナリオがあります。
4 に答える
ConcurrentHashMapは、書き込みと後続の読み取りの間に発生前の関係があることを保証します。そうです、(get)を読むと、「コミット」された(putが戻った)最新の変更が表示されます。
注:これは、javadocで説明されているイテレータには適用されません。
マップを「保持する」変数は、マップオブジェクトへの参照またはポインタです(それぞれ、マップが格納されているメモリアドレスへの(簡略化された))。揮発性にすることは、マップオブジェクト自体ではなく、ポインタにのみ影響します。常に同じMap-Objectを使用し、スレッドが使用する前にマップが完全に初期化されていることを確認する限り、マップへの「揮発性参照」を使用する必要はありません。並行性は、並行ハッシュマップ内で透過的に処理されます。
はい、ConcurrentHashMap
最新のビューを提供します。http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html#get(java.lang.Object)でjavadocsを参照すると、次の
ように明確に記述され ます。
取得は、開始時に保持されている最近完了した更新操作の結果を反映します
それにはもう少し詳細があります、そして私はあなたがそれを読んで行くことを提案します。
その上、すでに述べvolatile
たように、それはポインタにのみ影響し、マップの実際の内容には影響しないため、使用はあなたが望むものではありません。
マップを保持している参照が最終的なものであることを確認するだけで、適切に初期化されたマップが表示され、参照自体が変更されないことを保証する最終的なフィールドフェンスを取得できます。
他の人が指摘しているように、すべてのコレクションがそうConcurrentHashMap
であるように、内部での書き込みの前に可視性/発生を保証します。ただし、書き込みでのデータの競合を避けるためjava.util.concurrent.*
に、インターフェイスに公開されている条件付き書き込みを使用する必要があります。ConcurrentMap