Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentHashMap中是否可能有32个以上的锁_Java_Multithreading_Performance_Locking_Concurrenthashmap - Fatal编程技术网

Java ConcurrentHashMap中是否可能有32个以上的锁

Java ConcurrentHashMap中是否可能有32个以上的锁,java,multithreading,performance,locking,concurrenthashmap,Java,Multithreading,Performance,Locking,Concurrenthashmap,我读到ConcurrentHashMap在多线程中比Hashtable工作得更好,因为它在bucket级别拥有锁,而不是地图范围的锁。每个地图最多可能有32个锁。想知道为什么32个锁以及为什么不超过32个锁。默认值不是32,而是16。您可以使用以下命令覆盖它: 因此,您可以: Map<String, String> map = new ConcurrentHashmap<String, String)(128, 0.75f, 64); Map Map=new Concurre

我读到ConcurrentHashMap在多线程中比Hashtable工作得更好,因为它在bucket级别拥有锁,而不是地图范围的锁。每个地图最多可能有32个锁。想知道为什么32个锁以及为什么不超过32个锁。

默认值不是32,而是16。您可以使用以下命令覆盖它:

因此,您可以:

Map<String, String> map = new ConcurrentHashmap<String, String)(128, 0.75f, 64);

Map Map=new ConcurrentHashmap如果您谈论的是Java
ConcurrentHashmap
,那么限制是:

使用与给定映射相同的映射创建新映射。创建映射时,其容量为给定映射中映射数的1.5倍或16(以较大者为准),默认负载因子(0.75)和并发级别(16)

如果您阅读了本手册,就会清楚地看到,最大分段数为2^16,这应该足以满足近期任何可能的需求

您可能一直在考虑某些替代实验实现,例如:

此类支持32的硬连线预设并发级别。这允许最多32个put和/或remove操作同时进行


请注意,一般来说,当超过32个线程试图更新单个
ConcurrentHashMap

时,同步效率以外的因素通常是瓶颈。根据
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;
/**
*允许的最大分段数;习惯于束缚
*构造函数参数。
*/
静态最终整数最大分段=1个最大分段)
并发水平=最大分段数;

要使用所有默认并发级别16,您需要同时使用映射的16个内核。如果在25%的时间内只有32个核使用映射,那么一次只能使用16个段中的8个


总之,您需要有许多核心,它们都使用相同的映射,而不做其他事情。真正的程序通常不访问一个地图。

是的,默认值是16,但允许的最大值是32。我想知道为什么是32。我不知道你从哪里得到32。我正在查看源代码(Java6),但它没有提到32。这篇文章的日期是2003年8月21日,甚至早于Java5,因此它更像是一个预览。总是在其日期的上下文中考虑这样的信息。如果有疑问,请访问JDK源代码。@cletus一段时间以来,我一直在为一个问题绞尽脑汁,我环顾四周,但未能找到答案。我想知道如果
并发级别
大于映射的
容量
会发生什么。因此,默认情况下,两者都是16,这意味着每个桶都有一个锁。如果容量为32和并发级别
16,则将在两个铲斗上保持一个锁。但是当并发级别为32,容量为16时会发生什么?两个锁会被保存在同一个存储桶上吗?很好。非常感谢约翰。这个问题一周来一直困扰着我。@John是读者/作者/读者+作者的最大数量限制吗?我的答案中有一个到源代码的链接。你可能想读它来向自己证明最大值实际上大于32(它是2^16,或者mhaller提到的65536)。我在JavaSRC中跳过了这个。谢谢迈克。彼得,你能给我指一些关于这些细节的详细链接或参考资料吗?我认为这是合乎逻辑的。您拥有的核心/超线程数量决定了您可以拥有的活动线程数量;将其称为A。如果线程在映射中花费一定比例的时间,则将其称为P。假设您需要大约A*P段(可能更多以减少争用),因此,如果您有4个内核,并且它在映射中花费了25%的时间(对于做有用工作的程序来说,这将非常高),那么您需要大约4 x 25%的段,即1。你可以做数学题。对于你来说,核心的数量和你期望使用映射的时间百分比。命中缓存未命中将使当前线程/核心跳转到其他线程/核心,这并不是那么简单。缓存未命中经常发生,我不相信这会导致上下文切换。你所说的“跳出当前线程/核心到其他线程”是什么意思?@PeterLawrey这是否限制了最大读线程数/最大写线程数/最大(读写器+写器)线程数?
/**
 * 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;