简体   繁体   English

ConcurrentHashMap读写锁

[英]ConcurrentHashMap read and write locks

I am trying to find answer to these, but not able to find it on Google or in Java docs. 我试图找到这些答案,但无法在Google或Java文档中找到它。

Case 1: in ConcurrentHashMap , suppose a thread t1 is reading from segment n , and at same another thread t2 want to write on the same segment n : 情况1:ConcurrentHashMap ,假设一个线程t1从段n读取,并且在同一个另一个线程t2想要在同一段n上写入:

Question 1: will these two operations will be one after another, or they will execute simultaneously? 问题1:这两个操作将是一个接一个,还是会同时执行?


Case 2: in ConcurrentHashMap , suppose a thread t1 is writing on segment n , and at same another thread t2 want to read from the same segment n , 情况2:ConcurrentHashMap ,假设一个线程t1在段n上写入,并且在同一个另一个线程t2想要从同一段n读取,

Question 2: will these two operations will be one after another, or they will execute simultaneously? 问题2:这两个操作将是一个接一个,还是会同时执行?

I think javadoc answers both your questions: 我想javadoc会回答你的两个问题:

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). 检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠。 Retrievals reflect the results of the most recently completed update operations holding upon their onset. 检索反映了最近完成的更新操作的结果。 For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries. 对于诸如putAll和clear之类的聚合操作,并发检索可能反映仅插入或删除某些条目。

Segments are for update operations: 细分用于更新操作:

The allowed concurrency among update operations is guided by the optional concurrencyLevel constructor argument (default 16), which is used as a hint for internal sizing. 更新操作之间允许的并发性由可选的concurrencyLevel构造函数参数(缺省值16)引导,该参数用作内部大小调整的提示。

So, in short, reads are not blocked (it is implemented as reading volatile variables). 因此,简而言之,读取不会被阻止(它被实现为读取volatile变量)。 Writes could block each other if they write in the same segment. 如果写入在同一段中,则写入可能会相互阻塞。

According to ConcurrentHashMap Oracle docs, 根据ConcurrentHashMap Oracle文档,

The constructor of ConcurrentHashMap looks like this : ConcurrentHashMap的构造函数如下所示:

public ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel) public ConcurrentHashMap(int initialCapacity,float loadFactor,int concurrencyLevel)

So the above line creates a new, empty map with the specified initial capacity, load factor and concurrency level. 因此,上面的行创建了一个具有指定初始容量,加载因子和并发级别的新的空映射。 where, Important Parameters to consider from ConcurrentHashMap Constructor: 其中,ConcurrentHashMap构造函数要考虑的重要参数:

  • initialCapacity - the initial capacity. initialCapacity - 初始容量。 The implementation performs internal sizing to accommodate this many elements. 该实现执行内部大小调整以适应这么多元素。
  • concurrencyLevel - the estimated number of concurrently updating threads. concurrencyLevel - 并发更新线程的估计数量。 The implementation performs internal sizing to try to accommodate this many threads. 该实现执行内部大小调整以尝试容纳这么多线程。

In the ConcurrentHashMap Api , you will find the following constants. 在ConcurrentHashMap Api中,您将找到以下常量。

  • static final int DEFAULT_INITIAL_CAPACITY = 16; static final int DEFAULT_INITIAL_CAPACITY = 16;
  • static final int DEFAULT_CONCURRENCY_LEVEL = 16; static final int DEFAULT_CONCURRENCY_LEVEL = 16;

initial capacity parameter and concurrency level parameters of ConcurrentHashMap constructor (or Object) are set to 16 by default. 默认情况下,ConcurrentHashMap构造函数(或Object)的初始容量参数和并发级别参数设置为16。

Thus, instead of a map wide lock, ConcurrentHashMap maintains a list of 16 locks by default ( number of locks equal to the initial capacity , which is by default 16) each of which is used to lock on a single bucket of the Map.This indicates that 16 threads (number of threads equal to the concurrency level , which is by default 16) can modify the collection at the same time , given ,each thread works on different bucket. 因此,ConcurrentHashMap默认情况下维护一个包含16个锁的列表(锁的数量等于初始容量,默认情况下为16),而不是地图宽锁,每个锁用于锁定Map的单个存储桶。表示16个线程(线程数等于并发级别,默认为16)可以同时修改集合,给定每个线程在不同的存储桶上工作。 So unlike hashtable, we perform any sort of operation ( update ,delete ,read ,create) without locking on entire map in ConcurrentHashMap. 因此,与hashtable不同,我们执行任何类型的操作(更新,删除,读取,创建),而无需在ConcurrentHashMap中锁定整个映射。

Retrieval operations (including get) generally do not block. 检索操作(包括get)一般不会阻塞。 It uses the concept of volatile in this case. 在这种情况下,它使用volatile的概念。 , so may overlap with update operations (including put and remove). ,因此可能与更新操作重叠(包括put和remove)。 Retrievals reflect the results of the most recently completed update operations holding upon their onset. 检索反映了最近完成的更新操作的结果。

The allowed concurrency among update operations is guided by the optional concurrencyLevel constructor argument (default 16), which is used as a hint for internal sizing. 更新操作之间允许的并发性由可选的concurrencyLevel构造函数参数(缺省值16)引导,该参数用作内部大小调整的提示。 The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. 该表在内部进行分区,以尝试允许指定数量的并发更新而不会发生争用。 Because placement in hash tables is essentially random, the actual concurrency will vary. 因为散列表中的放置基本上是随机的,所以实际的并发性会有所不同。 Ideally, you should choose a value to accommodate as many threads as will ever concurrently modify the table. 理想情况下,您应该选择一个值来容纳与同时修改表一样多的线程。 Using a significantly higher value than you need can waste space and time, and a significantly lower value can lead to thread contention. 使用比您需要的更高的值会浪费空间和时间,而显着更低的值可能导致线程争用。

I hope it helps! 我希望它有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM