簡體   English   中英

Concurrenthashmap迭代器數據結構

[英]Concurrenthashmap Iterator data structure

我需要詢問ConcurrentHashMap的以下方面,因為我無法從源代碼中找出來。
(請注意,我並不是在詢問行為,這是眾所周知的。它是關於迭代器顯示行為的機制)

"The iterator is guaranteed to reflect the state of the map at the time of it's creation."

1.這是否意味着迭代器獲得了自己的備份映射副本? 為什么即使在創建迭代器之后,易失性讀取也無法給出“值”的真實狀態? (代碼的確切位置將不勝感激)

2.即使段正在進行重新哈希處理,無阻塞讀取和迭代如何仍能保持一致的行為?

正如評論中提到的,我不認為ConcurrentHashMap行為是“很好理解的”。 對於ConcurrentHashMap,在未歸因引用中做出的斷言不正確。

ConcurrentHashMap的迭代器是弱一致性的 ... Javadoc指出:

迭代器,拆分器和枚舉返回的元素反映了在創建迭代器/枚舉時或此后某個時刻哈希表的狀態。

有鑒於此,

您對問題1的簡短回答是: 不,它沒有獲得自己的地圖副本

對問題2的簡短回答是: 不是 “表現一致”


以下是來自Javadocs的其他一些相關引號,有助於解釋該實現:

基本策略是將表細分為細分,細分本身就是一個並發可讀的哈希表...

段維護着一個始終保持一致狀態的條目列表表,因此無需鎖定即可讀取(通過段和表的易失性讀取)。 這需要在調整表大小時在必要時復制節點,因此仍然使用舊版本表的讀者可以遍歷舊列表。

節點復制以其重新哈希方法針對每個段發生。 Segment.rehash()方法的javadocs解釋了該功能:

將每個列表中的節點重新分類為新表。 因為我們使用的是2的冪次展開,所以每個bin中的元素必須保持相同的索引或以2個偏移量的冪移動。 通過捕獲舊節點因為其下一個字段不會更改而可以重復使用的情況,我們消除了不必要的節點創建。 統計上,在默認閾值下,當表加倍時,僅其中的六分之一需要克隆。 一旦它們被並發遍歷表中的任何讀取器線程不再引用,它們替換的節點將立即被垃圾回收。 條目訪問使用純數組索引,因為它們后面是易失表寫入。

請參閱Richard Burnison的精彩文章 ,以更好地概述針對jdk 7的ConcurrentHashMap的實現細節。


了解更多信息:

用於ConcurrentHashMap jdk8的Javadocs

ConcurrentHashMap(openjdk-7)的源代碼

ConcurrentHashMap返回一個弱一致性迭代器,為什么我們還是應該使用它呢?

暫無
暫無

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

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