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