ConcurrentHashMap の形式のオブジェクト ストアを持つ既存のコードを使用しています。マップ内には、複数のスレッドで使用される変更可能なオブジェクトが格納されています。設計上、2 つのスレッドが同時にオブジェクトを変更しようとすることはありません。私の懸念は、スレッド間の変更の可視性に関するものです。
現在、オブジェクトのコードは「セッター」で同期されています (オブジェクト自体によって保護されています)。「ゲッター」には同期がなく、メンバーは揮発性ではありません。これは、私にとって、可視性が保証されていないことを意味します。ただし、オブジェクトが変更されると、マップに再配置put()
されます (同じキーでメソッドが再度呼び出されます)。これは、別のスレッドがマップからオブジェクトをプルすると、変更が表示されるということですか?
これについては、stackoverflow、JCIP、および java.util.concurrent のパッケージの説明で調査しました。私は基本的に自分自身を混乱させたと思います...しかし、この質問をするようになった最後のストローは、パッケージの説明からのものでした。
オブジェクトを並行コレクションに配置する前のスレッド内のアクションは、別のスレッド内のコレクションからのその要素へのアクセスまたは削除に続くアクションの前に発生します。
私の質問に関連して、「アクション」には、re-put() の前にマップに格納されたオブジェクトへの変更が含まれますか? これらすべてがスレッド間の可視性につながる場合、これは効率的なアプローチですか? 私はスレッドに比較的慣れていないので、コメントをいただければ幸いです。
編集:
皆様、ご回答ありがとうございます!これは StackOverflow に関する私の最初の質問であり、非常に役に立ちました。
それが私の混乱を最も明確に解決したと思うので、私はptomliの答えに行かなければなりません。つまり、この場合、「前に発生」関係を確立しても、必ずしも変更の可視性に影響するわけではありません。私の「タイトルの質問」は、テキストで説明されている実際の質問に関して構成が不十分です。ptomliの答えは、私がJCIPで読んだものと一致するようになりました。オブジェクトをマップに再配置しても、挿入されたオブジェクトのメンバーを変更するためのこの共通ロックは提供されません。
変更に関するすべてのヒント (不変オブジェクトなど) に感謝し、心から同意します。しかし、この場合、前述したように、慎重にスレッドを処理するため、同時変更はありません。1 つのスレッドがオブジェクトを変更し、後で別のスレッドがそのオブジェクトを読み取ります (CHM がオブジェクト コンベアです)。私が提供した状況を考えると、後で実行するスレッドが最初から変更を確認できるようにするには、CHM が不十分だと思います。しかし、タイトルの質問に正解した方も多いと思います。