ConcurrentHashMap中是否可以有超过32个锁

时间:2009-11-22 15:35:51

标签: java multithreading performance locking concurrenthashmap

我读到ConcurrentHashMap在多线程方面比Hashtable更好,因为在桶级别而不是映射范围锁定。每张地图最多可锁32次。想知道为什么32,为什么不超过32锁。

4 个答案:

答案 0 :(得分:8)

如果您在谈论Java ConcurrentHashMap,那么限制为arbitrary

  

使用与给定地图相同的映射创建新地图。创建的映射的容量是给定映射中映射数的1.5倍或16(以较大者为准),默认加载因子(0.75)和concurrencyLevel(16)。

如果你阅读source code,很明显最大段数是2 ^ 16,这对于不久的将来任何可能的需求都应该足够了。

您可能一直在考虑某些替代实验性实施,例如this one

  

此类支持硬连线预设并发级别32.这允许最多32个put和/或remove操作同时进行。

请注意,通常,当超过32个线程尝试更新单个ConcurrentHashMap时,除了同步效率之外的因素通常是瓶颈。

答案 1 :(得分:4)

默认值不是32,它是16.你可以用constructor argument 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。

答案 2 :(得分: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;

答案 3 :(得分:2)

要使用16的所有默认并发级别,您需要在同一时刻使用地图拥有16个核心。如果你有25个核心只使用地图25%的时间,那么一次只能使用16个中的8个。

总之,你需要拥有大量核心,所有核心都使用相同的地图而不做其他任何事情。真正的程序通常会执行除访问一个地图之外的其他操作。