簡體   English   中英

ConcurrentHashMap讀寫鎖

[英]ConcurrentHashMap read and write locks

我試圖找到這些答案,但無法在Google或Java文檔中找到它。

情況1:ConcurrentHashMap ,假設一個線程t1從段n讀取,並且在同一個另一個線程t2想要在同一段n上寫入:

問題1:這兩個操作將是一個接一個,還是會同時執行?


情況2:ConcurrentHashMap ,假設一個線程t1在段n上寫入,並且在同一個另一個線程t2想要從同一段n讀取,

問題2:這兩個操作將是一個接一個,還是會同時執行?

我想javadoc會回答你的兩個問題:

檢索操作(包括get)通常不會阻塞,因此可能與更新操作(包括put和remove)重疊。 檢索反映了最近完成的更新操作的結果。 對於諸如putAll和clear之類的聚合操作,並發檢索可能反映僅插入或刪除某些條目。

細分用於更新操作:

更新操作之間允許的並發性由可選的concurrencyLevel構造函數參數(缺省值16)引導,該參數用作內部大小調整的提示。

因此,簡而言之,讀取不會被阻止(它被實現為讀取volatile變量)。 如果寫入在同一段中,則寫入可能會相互阻塞。

根據ConcurrentHashMap Oracle文檔,

ConcurrentHashMap的構造函數如下所示:

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

因此,上面的行創建了一個具有指定初始容量,加載因子和並發級別的新的空映射。 其中,ConcurrentHashMap構造函數要考慮的重要參數:

  • initialCapacity - 初始容量。 該實現執行內部大小調整以適應這么多元素。
  • concurrencyLevel - 並發更新線程的估計數量。 該實現執行內部大小調整以嘗試容納這么多線程。

在ConcurrentHashMap Api中,您將找到以下常量。

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

默認情況下,ConcurrentHashMap構造函數(或Object)的初始容量參數和並發級別參數設置為16。

因此,ConcurrentHashMap默認情況下維護一個包含16個鎖的列表(鎖的數量等於初始容量,默認情況下為16),而不是地圖寬鎖,每個鎖用於鎖定Map的單個存儲桶。表示16個線程(線程數等於並發級別,默認為16)可以同時修改集合,給定每個線程在不同的存儲桶上工作。 因此,與hashtable不同,我們執行任何類型的操作(更新,刪除,讀取,創建),而無需在ConcurrentHashMap中鎖定整個映射。

檢索操作(包括get)一般不會阻塞。 在這種情況下,它使用volatile的概念。 ,因此可能與更新操作重疊(包括put和remove)。 檢索反映了最近完成的更新操作的結果。

更新操作之間允許的並發性由可選的concurrencyLevel構造函數參數(缺省值16)引導,該參數用作內部大小調整的提示。 該表在內部進行分區,以嘗試允許指定數量的並發更新而不會發生爭用。 因為散列表中的放置基本上是隨機的,所以實際的並發性會有所不同。 理想情況下,您應該選擇一個值來容納與同時修改表一樣多的線程。 使用比您需要的更高的值會浪費空間和時間,而顯着更低的值可能導致線程爭用。

我希望它有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM