3

私はさまざまな情報源からいくつかの声明を読み、ConcurrentHashmapそれらが本当にそうであるかどうかを確認したかった.

  1. a の反復子ConcurrentHashmapが作成された後は、スレッドによる削除操作と更新操作のみが反映されることが保証されます。イテレータは、編集/削除後にスナップショットを更新しますか? イテレータが更新/削除を ADD とは異なる方法で処理するのはなぜですか。

  2. ConcurrentHashmapデータをセグメントにシャードして、ライター ロックの競合を減らします。このconcurrencyLevelパラメーターは、クラスによって内部的に作成されるシャードの数を直接指定します。パラメーターなしのコンストラクターを単純に使用し、デフォルトの構成を受け入れると、最初の値を追加する前に、マップは 16 個のシャードに必要なオブジェクトをインスタンス化します…ここでシャードとは何を意味するのでしょうか? それはマップ内のデータのバケットですか、それともマップ全体のコピーですか。これは、更新を個別にロックできるデータベース内のページに似ていると理解しました。では、なぜconcurrencyLevel記憶に影響を与えるのでしょうか?

4

3 に答える 3

1
  1. entrySet 列挙を参照している場合、これは (最終的に) 親オブジェクトで実行された追加操作と削除操作の両方を反映します。ただし、列挙自体は追加操作をサポートしていません。

  2. この場合のシャーディングは、基本的にハッシュテーブルのハッシュテーブルです。ConcurrentHashMap のバッキング配列に 1024 個のエントリが含まれているとします。シャーディングがなければ、これはオブジェクトのハッシュ値が [0, 1023] の間の整数にマップされることを意味します。シャーディングでは、バッキング配列に 64 エントリのバッキング配列が 16 個含まれていることを意味します。つまり、[0, 1023] バッキング配列は [0, 63] からの配列、[64, 127] からの別の配列などになります。 ' 100 にハッシュされるオブジェクトを変更している - シャーディングを使用しない場合、[0, 1023] バッキング配列全体がロックされますが、シャーディングを使用すると、[64, 127] サブ配列のみがロックされ、追加のスレッドが変更できるようになります他の破片。シャードが多いほど、ConcurrentHashMap の同時実行性が高くなります。ただし、シャードが多いほど、それらを維持するために必要なメモリが多くなります。(ただし、これは相乗効果ではありません。16 個のシャードを使用すると、使用されるメモリの合計量が 16 倍になります。代わりに、これは相加効果です。各シャードのデータ構造を維持するのに 64 バイトかかるとしましょう。したがって、16 個のシャードを使用するとデータ構造に 1024 バイトが追加され、64 個のシャードを使用するとデータ構造に 4096 バイトが追加されます。)

于 2013-04-08T18:07:33.567 に答える