2012-10-05 118 views
4

我對Java中的ConcurrentHashMap有個疑問。它在內部調用readValueUnderLock。爲什麼在獲得操作的情況下需要鎖定。在這種情況下,這種情況將是真的 (Entry.value == null) 這會導致readValueUnderLock被調用)爲什麼ConcurrentHashMap中的方法阻塞?

回答

0

爲了從哈希映射中讀取值,代碼必須首先找到值。如果另一個線程在第一個線程正在查找該值時添加了一個值,則可能會導致搜索失敗。從本質上講散列圖可以這樣做:

calculate hash 
go to location hash in the array 
look to see if there's a list 
iterate through the list until value is found 

如果這個名單是說一個數組列表和其它線程需要調整它的大小,這將是該線程通過它遍歷一個大問題。

4

readValueUnderLock

/** 
    * Reads value field of an entry under lock. Called if value 
    * field ever appears to be null. This is possible only if a 
    * compiler happens to reorder a HashEntry initialization with 
    * its table assignment, which is legal under memory model 
    * but is not known to ever occur. 
    */ 

源代碼的Java文檔註釋從這個link

不太。你是對的,它永遠不應該被稱爲。 然而,JLS/JMM可以作爲閱讀不是絕對 被調用,因爲在決賽中所需的排序關係弱點 的 VS在構造函數設置揮發禁止它(關鍵是最終的,價值是 揮發),WRT的讀取由線程使用 條目對象。 (在JMM-ese中, 決賽的排序限制不在同步關係之外。) 這是doc評論(以下粘貼)引用的問題。 沒有人想過處理器/編譯器可能會發現產生空值讀取的實際漏洞, ,並且可以證明沒有任何漏洞存在(也許有一天,JLS/JMM修訂版將填補空白以闡明這個), 但是比爾·普格曾經建議我們爲了保守地迂迴正確而將它放在了 之內。 回想起來,我不太確定這是一個好主意,因爲 它導致人們想出奇特的理論。

+0

但不知道如何HashEntry初始化可以重新排序與它的表分配,我想了解在哪個條件中鍵不會爲空,值可能爲空,從Java文檔它似乎也不知道曾經發生過,那麼爲什麼他們包括這種方法來鎖定(因爲HashEntry是有效的免除所有字段是最終的,除了易變的值) – tarunk

+0

@tarunk從javadoc看起來它是爲特殊情況寫的。 –

+0

是的,任何關於這種特殊情況的想法,它是如何發生的,因爲jsr 133提供了對最終/易失變量進行排序的保證。 – tarunk

相關問題