ConcurrentHashMap は、マップ全体のロックではなくバケット レベルでロックを行うため、Hashtable よりもマルチスレッドでうまく機能することを読みました。マップごとに最大 32 個のロックが可能です。なぜ 32 で、なぜ 32 を超えないのか知りたいです。
4 に答える
Java について話している場合ConcurrentHashMap
、制限は任意です。
指定されたマップと同じマッピングで新しいマップを作成します。マップは、指定されたマップ内のマッピング数の 1.5 倍または 16 (どちらか大きい方) の容量と、デフォルトの負荷係数 (0.75) および concurrencyLevel (16) で作成されます。
ソース コードを読むと、セグメントの最大数が 2^16 であることが明らかです。これは、近い将来に考えられるあらゆるニーズに対して十分すぎるはずです。
次のような特定の代替実験的実装を考えているかもしれません:
このクラスは、32 のハードワイヤード プリセット同時実行レベルをサポートします。これにより、最大 32 の put および/または remove 操作を同時に進めることができます。
一般に、32 を超えるスレッドが 1 つのConcurrentHashMap
.
デフォルトは 32 ではなく、16 です。また、コンストラクター引数concurrency level
でオーバーライドできます。
public ConcurrentHashMap(int initialCapacity,
float loadFactor,
int concurrencyLevel)
あなたができるように:
Map<String, String> map = new ConcurrentHashmap<String, String)(128, 0.75f, 64);
64 に変更します。デフォルトは次のとおりです (Java 6u17 以降)。
initialCapacity
: 16;loadFactory
: 0.75f;concurrencyLevel
: 16.
のソースによると、ConcurrentHashMap
許可される最大値は次の65536
とおりです。
/**
* The maximum number of segments to allow; used to bound
* constructor arguments.
*/
static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
public ConcurrentHashMap(int initialCapacity,
float loadFactor, int concurrencyLevel) {
if (concurrencyLevel > MAX_SEGMENTS)
concurrencyLevel = MAX_SEGMENTS;
デフォルトの同時実行レベル 16 をすべて使用するには、マップを同時に使用する 16 個のコアが必要です。マップを 25% の時間しか使用しない 32 個のコアがある場合、一度に使用されるのは 16 個のセグメントのうち 8 個だけです。
要約すると、すべて同じマップを使用し、他に何もしない多くのコアが必要です。実際のプログラムは通常、1 つのマップにアクセスする以外のことを行います。