我读到ConcurrentHashMap在多线程方面比Hashtable更好,因为在桶级别而不是映射范围锁定。每张地图最多可锁32次。想知道为什么32,为什么不超过32锁。
答案 0 :(得分:8)
如果您在谈论Java ConcurrentHashMap
,那么限制为arbitrary:
使用与给定地图相同的映射创建新地图。创建的映射的容量是给定映射中映射数的1.5倍或16(以较大者为准),默认加载因子(0.75)和concurrencyLevel(16)。
如果你阅读source code,很明显最大段数是2 ^ 16,这对于不久的将来任何可能的需求都应该足够了。
您可能一直在考虑某些替代实验性实施,例如this one:
此类支持硬连线预设并发级别32.这允许最多32个put和/或remove操作同时进行。
请注意,通常,当超过32个线程尝试更新单个ConcurrentHashMap
时,除了同步效率之外的因素通常是瓶颈。
答案 1 :(得分:4)
默认值不是32,它是16.你可以用constructor argument 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。答案 2 :(得分: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;
答案 3 :(得分:2)
要使用16的所有默认并发级别,您需要在同一时刻使用地图拥有16个核心。如果你有25个核心只使用地图25%的时间,那么一次只能使用16个中的8个。
总之,你需要拥有大量核心,所有核心都使用相同的地图而不做其他任何事情。真正的程序通常会执行除访问一个地图之外的其他操作。