Java:ConcurrentHashMap 的 ConcurrencyLevel 值

shr*_*000 4 java concurrent-programming

ConcurrencyLevel 是否有一些最佳值,超出 ConcurrentHashMap 的性能开始下降?

如果是,该值是多少,性能下降的原因是什么?(这个问题源于试图找出 ConcurrentHashMap 可能具有的任何实际限制)。

NPE*_*NPE 5

Javadoc中提供非常详细的指导意见:

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

该表在内部进行了分区,以尝试允许指定数量的并发更新而不会发生争用。因为散列表中的放置本质上是随机的,所以实际的并发性会有所不同。理想情况下,您应该选择一个值来容纳尽可能多的线程同时修改表。使用明显高于您需要的值会浪费空间和时间,而明显较低的值会导致线程争用。但一个数量级内的高估和低估通常不会产生太大的影响。当已知只有一个线程会修改而所有其他线程只会读取时,值 1 是合适的。

总结一下:最佳值取决于预期的并发更新数。一个数量级内的值应该可以很好地工作。超出该范围的值可能会导致性能下降。

  • @shrini1000:我怀疑是否存在一个通用数字,即对于“N”,事情真的很有效,而对于“N+1”则停止。性能下降更有可能是渐进的;此外,这可能取决于很多因素。如果您想获得一些与您的环境相关的数字,我建议您设置一些基准。 (2认同)

Pet*_*rey 5

你必须问自己两个问题

  • 我有多少个 CPU?
  • 一个有用的程序访问同一张地图的时间百分比是多少?

第一个问题告诉您可以同时访问地图的最大线程数。您可以有 10000 个线程,但如果您只有 4 个 cpu,则最多同时运行 4 个。

第二个问题告诉您,这些线程中的大多数将访问地图并做一些有用的事情。您可以优化地图来做一些无用的事情(例如微基准测试),但恕我直言,没有必要进行调整。假设您有一个非常有用的程序,它经常使用地图。它可能花费 90% 的时间做其他事情,例如 IO、访问其他地图、构建键或值、使用从地图获取的值做一些事情。

假设您在具有 4 个 CPU 的机器上花费 10% 的时间访问地图。这意味着您平均将在 0.4 个线程中访问地图。(或者大约 40% 的时间是一个线程)在这种情况下,1-4 的并发级别就可以了。

在任何情况下,即使对于微基准测试,将并发级别设置为高于您拥有的 CPU 数量也可能是不必要的。