我想了解锁定在Java ConcurrentHashMap中是如何工作的。根据源代码here,对于每次读取,它看起来都是使用该特定段的锁来锁定读取器。我弄错了吗?
V readValueUnderLock(HashEntry<K,V> e) {
lock();
try {
return e.value;
} finally {
unlock();
}
}
答案 0 :(得分:5)
下面没有锁定每个Read是方法readValueUnderLock
的文档读取锁定条目的值字段。 永远调用值字段 似乎为空。只有在编译器发生时才有可能 使用表分配重新排序HashEntry初始化,即 在内存模式下合法,但不知道发生。
读入ConcurrentHashMap不会在整个地图上同步。除了在一个条件下,Infact遍历根本不同步。内部LinkedList实现知道对底层集合的更改。如果它在遍历期间检测到任何此类更改,则它会在其正在遍历的存储桶上同步,然后尝试重新读取这些值。这始终确保虽然收到的值总是新鲜的,但如果有的话,则存在简约锁定。
以下是此类中的get实现只有当v为null时才会调用readValueUnderLock
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}