2016-10-27 21 views
1

put(),clear()およびremove()は、ConcurrentHashMapによって提供され、ロックを使用せずにスレッドセーフな操作です。ConcurrentHashMap remove()スレッドBを使用して反復処理中にスレッド

ConcurrentHashMapには、異なるセグメントがあり、各セグメントにはいくつかのハッシュバケットがあります。 clear()がちょうどそのバケットが、ハッシュチェーンのハッシュチェーンへの参照をクリアするため

Clear()put()スレッドががそれを反復されている場合、それが影響を受けたが、clear()からされることはありませんので、まだそこにあるスレッドセーフですスレッドBPut()は、そのバケットのハッシュチェーンの先頭に常に新しいノードを配置するので、それも問題ありません。

しかし、私が理解していないのは、なぜremove()がスレッドセーフなのでしょうか?例えば、ハッシュバケットはバケット→A→B→C→D→EスレッドAremove(C)となり、ConcurrentHashMapの実装で提供されるメカニズムはA、Bを次のリンクされたリストが逆順でバケット→B-> A-> DEとなり、A.nextを元のD-> Eとすると、バケット→B→A→DEとなります。

これはスレッドセーフなのはなぜですか?現在、thread Bが要素Aを反復処理していて、次にthread Aがremove(C)を呼び出すとどうなりますか?それは壊れるように見えますか?

+0

どのような「壊れた」と言っていますか? –

答えて

1

まあ、remove()クローンHashEry要素は削除された要素まで、古い要素は変更しません。ですから、

B *を取得 - > A * - バケツに> D-> Eのが、元

A-> B-> C- ^シーケンスは触れていません。

等価キーと等しい値を持つにもかかわらず、A.equals(A *)== falseを確実にすることができます。しかし、それはイテレータの問題ではありません。単に、すでに取得済みのエントリAを使用して移動するだけです。

P.S. ConcurrentHashMapは、変更のためにバケットレベルのロックを使用します。ロックフリーではありません。

+0

パーフェクト、完璧な意味合いをしてください。 –