【问题标题】:What guarantee does concurrencyLevel argument of ConcurrentHashMap give us?ConcurrentHashMap 的 concurrencyLevel 参数给了我们什么保证?
【发布时间】:2012-08-25 08:46:53
【问题描述】:

来自 ConcurrentHashMap 的 Javadocs:

更新操作之间允许的并发由 可选的 concurrencyLevel 构造函数参数(默认 16),即 用作内部尺寸调整的提示。

我不明白“用作内部尺寸调整提示”的部分。 .这是什么意思 ?设置此值的最佳做法是什么?它为我们提供了什么保证?

【问题讨论】:

    标签: java data-structures hashtable java.util.concurrent


    【解决方案1】:

    并发级别大约等于可以在不使用内部锁定机制的情况下同时调用 map 上的操作数。正如 maat b 所说,ConcurrentHashMap 将有 N 个内部哈希表,因此在不同哈希表上工作的操作不需要额外的锁定 - 否则,如果操作在同一个内部哈希表上工作,那么 ConcurrenyHashMap 会对它们使用额外的内部锁定。

    【讨论】:

    • @kodstack 是多少并发操作或多少并发写操作?
    • @Geek 这可能是内部问题 - 基本上 ConcurrentHashMap 保证比标准 HashMap 更少的锁定 - 可以通过性能测试来验证输入参数组合的其他要求。
    【解决方案2】:

    看看 Javadoc 中的下一句:

    该表在内部进行了分区以尝试允许指定的 无争用的并发更新数。因为安置 在哈希表中本质上是随机的,实际的并发将 各不相同。理想情况下,您应该选择一个值来容纳尽可能多的 线程将同时修改表。用一个 显着高于您需要的价值会浪费空间和时间, 并且显着降低的值会导致线程争用。但 高估和低估一个数量级 通常不会产生太大的影响。值为 1 是 当已知只有一个线程会修改并且 所有其他人只会阅读。此外,调整这个或任何其他类型的 哈希表是一个相对较慢的操作,所以,如果可能,它是 提供对预期表大小的估计的好主意 构造函数。

    换句话说,concurencyLevel 为 16 意味着 ConcurrentHashMap 在内部创建了 16 个单独的哈希表来存储数据。修改一个哈希表中的数据的操作不需要锁定其他哈希表,这允许对整个 Map 进行一定程度的并发访问。

    您可能想尝试阅读the source of ConcurrentHashMap。

    【讨论】:

    • 这 16 个哈希表的大小是多少?
    • ConcurrentHashMap 在内部创建 16 个单独的哈希表来存储数据。 - 很好的信息。
    • @matt 你也能解释一下“它被用作内部尺寸的提示”。部分 。这里指的是什么尺寸?在这种情况下是 16 个哈希表的数量还是 16 个哈希表中每个哈希表的大小?
    • 内部哈希表没有最大大小限制;否则你的 ConcurrentHashMap 只能容纳 16 * max size 元素。同样,您可以查看类本身的来源,内部表创建部分发生在 line 629 并且“内部哈希表”定义为 Segment class
    • 注意我将源链接从 docjar.com 更改为 grepcode.com,前者似乎使用的是 JDK7 源,这与 JDK6 中附带的 ConcurrentHashMap 源不同
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 2013-06-28
    • 2018-07-21
    • 2014-11-04
    相关资源
    最近更新 更多