8

ConcurrentHashMap は、マップ全体のロックではなくバケット レベルでロックを行うため、Hashtable よりもマルチスレッドでうまく機能することを読みました。マップごとに最大 32 個のロックが可能です。なぜ 32 で、なぜ 32 を超えないのか知りたいです。

4

4 に答える 4

9

Java について話している場合ConcurrentHashMap、制限は任意です。

指定されたマップと同じマッピングで新しいマップを作成します。マップは、指定されたマップ内のマッピング数の 1.5 倍または 16 (どちらか大きい方) の容量と、デフォルトの負荷係数 (0.75) および concurrencyLevel (16) で作成されます。

ソース コードを読むと、セグメントの最大数が 2^16 であることが明らかです。これは、近い将来に考えられるあらゆるニーズに対して十分すぎるはずです。

次のような特定の代替実験的実装を考えているかもしれませ:

このクラスは、32 のハードワイヤード プリセット同時実行レベルをサポートします。これにより、最大 32 の put および/または remove 操作を同時に進めることができます。

一般に、32 を超えるスレッドが 1 つのConcurrentHashMap.

于 2009-11-22T15:47:03.610 に答える
5

デフォルトは 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.
于 2009-11-22T15:42:32.683 に答える
3

のソースによると、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;
于 2009-11-22T15:51:34.323 に答える
2

デフォルトの同時実行レベル 16 をすべて使用するには、マップを同時に使用する 16 個のコアが必要です。マップを 25% の時間しか使用しない 32 個のコアがある場合、一度に使用されるのは 16 個のセグメントのうち 8 個だけです。

要約すると、すべて同じマップを使用し、他に何もしない多くのコアが必要です。実際のプログラムは通常、1 つのマップにアクセスする以外のことを行います。

于 2009-11-29T09:52:13.903 に答える