为什么默认并发级别为ConcurrentHashMap
16,为什么不是18?
答案 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
,但这又应该是一个计算良好的数字,以获得最佳效果结果