ConcurrentHashMap 构造函数参数?

2022-09-01 23:37:07

我想知道构造一个:ConcurrentHashMap

  • initialCapacity默认为 16(可理解)。
  • loadFactor默认为 0.75。
  • concurrencyLevel默认值为 16。

我的问题是:

  • 应该使用什么标准来向上或向下调整?loadFactor
  • 如何确定并发更新线程的数量?
  • 应该使用什么标准来向上或向下调整?concurrencyLevel

此外:

  • 一个好的哈希码实现的标志是什么?(如果 SO 问题解决了这个问题,只需链接到它即可。

谢谢!


答案 1

简短的回答:将“初始容量”设置为您希望在映射中放置的大致数量,并将其他参数保留为默认值。

长答案:

  • 负载因子是映射中“存储桶”的数量与预期元素数量之间的比率;

  • 0.75通常是一个合理的折衷方案 - 正如我所记得的,这意味着使用良好的哈希函数,平均而言,我们期望大约1.6个重定向才能在地图上找到一个元素(或围绕该图);

    • 改变负载因子会改变更多重定向之间的折衷方案,以找到一个元素,但浪费的空间更少 - 放0.75通常是一个不错的值;

    • 原则上,将并发级别设置为您希望修改映射的并发线程数,尽管高估这一点除了浪费内存之外似乎并没有不良影响(如果您有兴趣,我不久前写了一些关于 ConcurrentHashMap 性能的文章)

非正式地说,你的哈希函数本质上应该旨在使位具有尽可能多的“随机性”。或者更严格地说,给定元素的哈希代码应该给每个位大约50%的设置机会。实际上,用一个例子来说明这一点更容易:同样,你可能对我写的一些关于字符串哈希函数如何工作以及相关的哈希函数指南的东西感兴趣。欢迎对任何此类内容进行反馈。

我在某些时候还提到的一件事是,你不必在实践中过于偏执:如果你的哈希函数在某些位中产生“合理”的随机性,那么它通常是可以的。在最坏的情况下,将代表性数据片段粘贴到字符串中并获取字符串的哈希代码实际上并不那么糟糕。


答案 2

负载因子主要与哈希函数的质量有关。负载因子越接近零,即使哈希函数不是那么好,发生冲突的可能性就越小。权衡是内存占用量更大。换句话说,HashMap不是将条目分布在每个单独哈希码的单独存储桶中,而是按邻近度对它们进行分组,因此它拥有的存储桶越多,分布就越分散,发生冲突的可能性就越小。

因此,底线是您可以根据需要和存储在地图中的对象来调整负载因子以缩短查找时间或减少内存。

并发级别实际上取决于您的应用程序。如果应用程序中只有两个或三个线程运行,则即可。如果您是具有任意线程数的应用程序服务器,那么您需要了解您的负载容量是多少以及要针对哪个点进行优化。

高质量的哈希代码实现在对象的潜在值之间提供尽可能广泛的分布,同时减少冲突次数,同时遵守契约。换句话说,它允许HashMap(或设置,视情况而定)将对象分发到单独的存储桶中,从而更快地进行查找。