ConcurrentHashMap的默认并发级别的原因

时间:2018-05-08 06:53:22

标签: java concurrency concurrenthashmap

为什么默认并发级别为ConcurrentHashMap 16,为什么不是18?

4 个答案:

答案 0 :(得分:2)

我刚检查了并发映射的实现,我发现了以下内容:

/**
 * The default concurrency level for this table. Unused but
 * defined for compatibility with previous versions of this class.
 */
private static final int DEFAULT_CONCURRENCY_LEVEL = 16;

似乎只是为了与旧版本兼容而定义。

对于为什么它16不是18的问题。我猜它是因为在实现中按位操作和更好的内存管理,它更好是2的幂。

答案 1 :(得分:1)

在JAVA 8之前

concurrencyLevel意味着并发hashmap需要多少内部哈希映射才能正常工作。这基本上意味着您应该编写一个值,指出将使用该并发hashmap的线程数。写入比实际线程更多的是性能损失并不是更多的内存丢失。为什么java开发人员决定选择16我只能猜测,但这可能是由于计算处理器上的内核等。你不需要18,因为你可能没有18个核心/线程CPU,你可以有16个。仍然是一个默认号码,所以为了获得最佳性能,你需要设置它。

在JAVA 8之后:

此并发级别不再使用;)仅出于与旧代码兼容的原因,它留在构造函数中。

答案 2 :(得分:0)

“为什么默认值不是我想要的值”的问题的基本答案通常是:因为您的用例是特定于您的,并且在一般情况下不一定是好的。

(另一个可能的答案是:他们选择了一个任意但合理的默认值。)

无论原因如何,它都具有该值,因此您可以使用具有默认值的类或其API来指定不同的值;或者你可以使用不同的课程;或者你可以为班级的维护者提供一个理由,说明为什么它应该有不同的价值。

在这种情况下,有一个构造函数允许您指定并发级别,因此只需指定所需的值。

答案 3 :(得分:0)

Concurrency Level表示shards的数量。 它用于将ConcurrentHashMap内部划分为此数量的分区,并创建相同数量的线程以维持碎片级别的线程安全性。 “concurrencyLevel”的默认值是

  

16

每当我们使用默认构造函数16 shards创建ConcurrentHashMap实例时,这意味着before even adding first key-value pair。 它还意味着为ConcurrentHashMap$Segment, ConcurrentHashMap$HashEntry[] and ReentrantLock$NonfairSync等各种内部类创建实例。

在正常应用的大多数情况下,

  

单个分片能够处理具有合理键值对数的多个线程。而且性能也是最佳的。拥有多个分片只会使内部的事情变得复杂,并为垃圾收集引入了许多不必要的对象,所有这些都没有提高性能。

最好保持concurrencyLevel最小化。 请注意,如果您使用very high concurrent application中的very high frequency of updates处理ConcurrentHashMap,那么只有您应该考虑increasing the concurrencyLevel,但这又应该是一个计算良好的数字,以获得最佳效果结果