Java の ConcurrentHashMap について質問があります。内部的に readValueUnderLock を呼び出します。get 操作の場合にロックが必要な理由。その場合、この条件は true (Entry.value==null) になり、readValueUnderLock が呼び出されます)
2 に答える
ソースコードのJava docコメントから readValueUnderLock
/**
* Reads value field of an entry under lock. Called if value
* field ever appears to be null. This is possible only if a
* compiler happens to reorder a HashEntry initialization with
* its table assignment, which is legal under memory model
* but is not known to ever occur.
*/
このリンクから
そうではありません。あなたはそれが決して呼び出されるべきではないというのは正しいです。ただし、JLS/JMM は、コンストラクターで設定された final と volatile の間で必要な順序関係 (キーは final、値は volatile) の順序関係に弱点があるため、呼び出されることを完全に禁止しているわけではないと読むことができます (エントリ オブジェクトを使用するスレッドによる読み取りに関して)。 . (JMM-ese では、finals の順序付けの制約は synchronizes-with 関係の範囲外になります。) これは、ドキュメント コメント (以下に貼り付け) が言及している問題です。プロセッサ/コンパイラがnull値の読み取りを生成するために見つける可能性のある実用的な抜け穴について誰も考えたことがありません.また、何も存在しないことが証明される可能性があります. Bill Pugh はかつて、控えめに言っても衒学的に正しいという理由だけで、とにかくこれを入れることを提案しました。
ハッシュマップから値を読み取るために、コードは最初に値を見つける必要があります。最初のスレッドが値を見つけている間に別のスレッドが値を追加すると、検索が狂う可能性があります。基本的に、ハッシュマップは次のようなことができます:
calculate hash
go to location hash in the array
look to see if there's a list
iterate through the list until value is found
このリストがたとえば配列リストであり、他のスレッドがそのサイズを変更する必要がある場合、これはそれを反復するスレッドにとって大きな問題になります。