ConcurrentHashMap构造函数参数?
我想知道有关参数的用于构造ConcurrentHashMap
:ConcurrentHashMap构造函数参数?
-
initialCapacity
是16由默认值(理解)。 -
loadFactor
默认为0.75。 -
concurrencyLevel
默认为16。
我的问题是:
- 什么标准应该被用来调整
loadFactor
向上或向下? - 我们如何建立并发更新线程的数量?
- 应该用什么标准调整
concurrencyLevel
向上或向下?
此外:
- 什么是一个好的哈希码实施的标志? (如果SO问题解决这个问题,只需链接到它。)
谢谢!
简短回答:将“初始容量”设置为您预期放置在地图上的映射数量,并将其他参数保留为默认值。
龙答案:
负载因素是 数在地图和 预期元件的数量“桶”的之间的比率;
-
0.75通常是一个合理的妥协 - 正如我记得,这意味着,与一个 良好的散列函数,平均我们 预计约1。6重定向,以在地图(或围绕该图)中找到 元素;
改变负载 因素变化 更多重定向之间的妥协找到一个元素,但 少浪费space--放0.75是 真的通常一个很好的价值;
原则,设置ConcurrencyLevel到 并发线程的数量,您 希望有修改地图, 虽然高估,这并不 似乎有其他 不是浪费记忆不好的影响(我写了一个小 上的情况下,ConcurrentHashMap performance 前一阵子你 感兴趣)
通俗地说,你的哈希函数应该基本上旨在尽可能多地在这些位中具有“随机性”。或者更严格地说,给定元素的哈希码应该给每个比特大概50%的机会被设置。用一个例子来说明这一点实际上更容易:再次,您可能对我写的关于how the String hash function works和相关的hash function guidelines的一些内容感兴趣。任何这些东西都欢迎反馈意见。
有一件事我也提到在某些时候是,你不必过于偏执的做法:如果你的哈希函数产生的位的一些“合理的”随机性的量,那么它通常会好的。在最坏的情况下,将代表性的数据片段粘贴到一个字符串中并采用该字符串的哈希代码实际上并不会如此糟糕。
loadFactor:控制实现何时决定调整散列表的大小。太高的价值会浪费空间;太低的值将导致昂贵的调整大小操作。
concurrencyLevel:指示实现尝试针对给定数量的写入线程进行优化。根据API文档,关闭10倍不会对性能产生太大影响。
更新 操作中允许的并发由可选 concurrencyLevel构造参数 (默认16),其被用作用于内部施胶的提示 引导。该表为 内部分区以尝试 允许指定数量的 并发更新而没有争用。 因为在散列表中放置的数据实质上是随机的,所以实际的并发性会有所不同。理想情况下,您应该选择一个值来容纳 尽可能多的线程,并且会同时修改该表。使用 明显高于你的值可能会浪费空间和时间,而明显更低的值可能导致 线程争用。但高估 并低估 的幅度通常不会有太大的 明显的影响。
一个好的散列码实现将在任何时间间隔内均匀散布散列值。如果事先知道该组密钥,则可以定义一个“完美”散列函数,为每个密钥创建一个唯一的散列值。
loadFactor设定为0.75默认情况下, 什么标准应该被用来调整 这种向上或向下?
您需要一些背景知道哈希映射如何工作,然后才能理解它的工作原理。地图本质上是一系列的桶。根据散列码的不同,映射中的每个值都会被放入一个存储桶中。该loadFactor意味着,如果桶超过75%满,地图应该调整
concurrencyLevel被 默认设置为16,我们如何建立 数量的并发更新 线程?应该用什么标准 来调整这个向上或向下?
这是问多少线程你希望并发修改地图(同时)
哈希代码,请参见约书亚布洛赫的Effective Java
负荷率主要与哈希的质量功能。即使散列函数不是很好,负载因子越接近零,碰撞的可能性越小。权衡是内存占用更大。换句话说,HashMap没有为每个独立的散列码在单独的桶中分布条目,而是将它们按邻域分组,因此它拥有的桶越多,分布越分散,出现冲突的可能性就越小。
因此,根据您的需求和您在Map中存储的对象,您可以根据负载因子调整查找时间或减少内存。
ConcurrencyLevel实际上取决于您的应用程序。如果你只有两个或三个线程在应用程序中运行,那么你就去。如果您是一个具有任意数量线程的应用程序服务器,那么您需要了解您的负载容量以及您希望优化的点数。
质量良好的散列码实现提供尽可能广泛的对象潜在值的分布,尽可能减少冲突次数,同时遵守合同。换句话说,它允许HashMap(或根据具体情况设置)将对象分布到单独的存储桶中,从而加快查找速度。
谢谢戴夫,好多了我会把我的队列从你身上 – 2009-10-15 17:58:47