代码之家  ›  专栏  ›  技术社区  ›  non sequitor

Concurrenthashmap构造函数参数?

  •  22
  • non sequitor  · 技术社区  · 15 年前

    我想知道构造 ConcurrentHashMap :

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

    我的问题是:

    • 应使用什么标准进行调整 载荷系数 向上还是向下?
    • 我们如何确定并发更新线程的数量?
    • 应使用什么标准进行调整 并发级别 向上还是向下?

    另外:

    • A的特征是什么? 好的 哈希代码实现?(如果某个问题解决了这个问题,只需链接到它即可。)

    谢谢您!

    4 回复  |  直到 15 年前
        1
  •  17
  •   Neil Coffey    15 年前

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

    长回答:

    • 负载系数是 图中的“bucket”数量和 预期元素的数量;

    • 0.75通常是一个合理的折中方案——我记得,这意味着 好的哈希函数,平均我们 预计1.6次重定向会找到 地图中的元素(或该图形周围的元素);

      • 改变负载 因素改变了两者之间的妥协 更多重定向以查找元素,但 减少浪费的空间——投入0.75是 通常是很好的价值观;

      • 原则上,将ConcurrencyLevel设置为 您的并发线程数 希望修改地图, 虽然高估了这一点 似乎对其他人有不良影响 比浪费记忆(我写了一点 在 ConcurrentHashMap performance 不久前,以防你 感兴趣)

    非正式地说,散列函数的基本目标应该是尽可能多地使用位中的“随机性”。或者更严格地说,给定元素的散列代码应该给每个位大约50%的设置机会。事实上,用一个例子来说明这一点比较容易:同样,你可能对我写的一些东西感兴趣 how the String hash function works 及相关 hash function guidelines .很明显,我们欢迎您对这些内容进行反馈。

    我在某一点上也提到了一件事,那就是你在实践中不必过于偏执:如果你的散列函数在 一些 在位,那么它通常是好的。在最坏的情况下,将代表性的数据块粘贴到字符串中,并获取字符串的哈希代码实际上并没有那么糟糕。

        2
  •  4
  •   Yishai    15 年前

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

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

    并发级别实际上取决于您的应用程序。如果应用程序中只运行了两个或三个线程,那么就可以了。如果您是一个拥有任意数量线程的应用服务器,那么您需要了解您的负载能力是什么,以及您希望优化的目标是什么。

    一个高质量的hashcode实现在遵守契约的同时,以最少的冲突次数,尽可能广泛地跨对象的潜在值分布。换句话说,它允许hashmap(或视情况设置)将对象分布到单独的存储桶中,从而加快查找速度。

        3
  •  0
  •   Jim Garrison    15 年前

    LoadFactor:控制实现何时决定调整哈希表的大小。值太高会浪费空间;值太低会导致昂贵的调整操作。

    concurrencylevel:告诉实现尝试针对给定数量的写入线程进行优化。根据API文档,最多关闭10个因素对性能不会有太大的影响。

    更新之间允许的并发性 操作由可选的 ConcurrencyLevel构造函数参数 (默认值16),用作提示 内部尺寸。桌子是 内部分区以尝试 允许指定数量的 无争用的并发更新。 因为哈希表中的位置是 基本上是随机的 并发性会有所不同。理想地,你 应选择一个值以适应 尽可能多的线程 同时修改表。使用A 价值明显高于你 需要会浪费时间和空间, 值显著降低会导致 线程争用。但是高估了 低估了 数量通常不多 显著影响。

    一个好的哈希代码实现将在任何间隔内均匀地分布哈希值。如果预先知道密钥集,则可以定义一个“完美”哈希函数,为每个密钥创建一个唯一的哈希值。

        4
  •  0
  •   Kevin    15 年前

    加载系数默认设置为0.75, 应使用什么标准进行调整 这个向上还是向下?

    在理解散列映射的工作方式之前,您需要了解散列映射的工作方式。地图基本上是一系列的桶。映射中的每个值都被放入一个桶中,这取决于它的哈希代码是什么。加载因子意味着,如果存储桶满了75%,则应调整映射的大小。

    ConcurrencyLevel由设置为16 违约,我们如何建立 同时更新的次数 线程?应该使用什么标准 上下调整?

    这将询问您希望多少线程同时(同时)修改映射。

    有关哈希代码,请参见Joshua Bloch的 Effective Java