并发哈希映射读写锁
我试图找到这些问题的答案,但无法在Google或Java文档中找到它。
情况 1:在 中,假设一个线程 t1 正在从段 n 读取,并且在同一个线程 t2 上写入同一段 n:ConcurrentHashMap
问题1:这两个操作是一个接一个地执行,还是同时执行?
情况 2:在 中,假设一个线程 t1 正在写入段 n,并且在同一个线程 t2 上想要从同一段 n 读取,ConcurrentHashMap
问题2:这两个操作是一个接一个,还是同时执行?
我试图找到这些问题的答案,但无法在Google或Java文档中找到它。
情况 1:在 中,假设一个线程 t1 正在从段 n 读取,并且在同一个线程 t2 上写入同一段 n:ConcurrentHashMap
问题1:这两个操作是一个接一个地执行,还是同时执行?
情况 2:在 中,假设一个线程 t1 正在写入段 n,并且在同一个线程 t2 上想要从同一段 n 读取,ConcurrentHashMap
问题2:这两个操作是一个接一个,还是同时执行?
我认为javadoc回答了你的两个问题:
检索操作(包括get)一般不阻塞,因此可能与更新操作(包括放置和删除)重叠。检索反映最近完成的更新操作在其开始时保持的结果。对于聚合操作(如 putAll 和 clear),并发检索可能仅反映插入或删除某些条目。
分段用于更新操作:
更新操作之间允许的并发性由可选的并发级别构造函数参数(默认值 16)指导,该参数用作内部大小的提示。
因此,简而言之,读取不会被阻止(它被实现为读取易失性变量)。如果写入在同一段中,则写入可能会相互阻止。
根据 ConcurrentHashMap Oracle 文档,
ConcurrentHashMap的构造函数如下所示:
public ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel)
因此,上面的行将创建一个具有指定初始容量、负载因子和并发级别的新的空映射。其中,ConcurrentHashMap 构造函数中要考虑的重要参数:
在 ConcurrentHashMap Api 中,您将找到以下常量。
默认情况下,ConcurrentHashMap 构造函数(或 Object)的初始容量参数和并发级别参数设置为 16。
因此,ConcurrentHashMap 默认维护一个包含 16 个锁的列表(锁数等于初始容量,默认情况下为 16 个),每个锁用于锁定 Map 的单个存储桶。这表示 16 个线程(线程数等于并发级别,默认情况下为 16 个)可以同时修改集合, 给定,每个线程在不同的存储桶上工作。因此,与哈希表不同,我们执行任何类型的操作(更新,删除,读取,创建),而无需锁定CurrentHashMap中的整个地图。
检索操作(包括 get)通常不会阻塞。在这种情况下,它使用易失性的概念,因此可能与更新操作(包括放置和删除)重叠。检索反映最近完成的更新操作在其开始时保持的结果。
更新操作之间允许的并发性由可选的并发级别构造函数参数(默认值 16)指导,该参数用作内部大小的提示。该表在内部分区,以尝试允许指定数量的并发更新而不会发生争用。由于哈希表中的位置基本上是随机的,因此实际并发性会有所不同。理想情况下,您应该选择一个值来容纳尽可能多的线程,以同时修改表。使用明显高于所需值的值会浪费空间和时间,而明显较低的值可能会导致线程争用。
我希望它有帮助!