2012-10-05 64 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

相关问题