我读到 ConcurrentHashMap 在多线程中比 Hashtable 工作得更好,因为在存储桶级别有锁而不是映射范围的锁。每张地图最多可以有 32 个锁。想知道为什么是32个,为什么不超过32个锁。
问问题
4586 次
4 回答
9
如果您在谈论 Java ConcurrentHashMap
,那么限制是任意的:
创建一个与给定地图具有相同映射的新地图。映射的容量是给定映射中映射数量的 1.5 倍或 16(以较大者为准),默认负载因子 (0.75) 和并发级别 (16)。
如果您阅读源代码,就会清楚最大段数为 2^16,这对于近期任何可以想象的需求应该绰绰有余。
您可能一直在考虑某些替代实验性实现,例如:
此类支持硬连线预设并发级别 32。这允许最多 32 个 put 和/或 remove 操作同时进行。
请注意,一般来说,当超过 32 个线程尝试更新单个ConcurrentHashMap
.
于 2009-11-22T15:47:03.610 回答
5
默认不是 32,而是 16。您可以使用构造函数参数concurrency level
覆盖它:
public ConcurrentHashMap(int initialCapacity,
float loadFactor,
int concurrencyLevel)
所以你可以这样做:
Map<String, String> map = new ConcurrentHashmap<String, String)(128, 0.75f, 64);
将其更改为 64。默认值为(从 Java 6u17 开始):
initialCapacity
: 16;loadFactory
: 0.75f;concurrencyLevel
: 16。
于 2009-11-22T15:42:32.683 回答
3
根据 的来源ConcurrentHashMap
,允许的最大值为65536
:
/**
* The maximum number of segments to allow; used to bound
* constructor arguments.
*/
static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
public ConcurrentHashMap(int initialCapacity,
float loadFactor, int concurrencyLevel) {
if (concurrencyLevel > MAX_SEGMENTS)
concurrencyLevel = MAX_SEGMENTS;
于 2009-11-22T15:51:34.323 回答
2
要使用所有默认的 16 并发级别,您需要有 16 个内核同时使用映射。如果您有 32 个核心仅在 25% 的时间内使用映射,那么一次将仅使用 16 个段中的 8 个。
总而言之,你需要有很多核心都使用同一张地图,并且什么都不做。真正的程序通常会做一些事情,而不是访问一张地图。
于 2009-11-29T09:52:13.903 回答