我想了解 Java ConcurrentHashMap 中的锁定是如何工作的。根据源代码here ,看起来每次读取都会使用该特定段的锁来锁定读取器。难道是我理解错了?
V readValueUnderLock(HashEntry<K,V> e) {
lock();
try {
return e.value;
} finally {
unlock();
}
}
最佳答案
每次读取都不会被锁定,下面是 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.
读取 ConcurrentHashMap 不会在整个映射上同步。事实上,除非在一种情况下,否则遍历根本不同步。内部 LinkedList 实现知道底层集合的更改。如果它在遍历期间检测到任何此类更改,它会在正在遍历的存储桶上进行自身同步,然后尝试重新读取值。这始终确保虽然接收到的值始终是最新的,但存在简约锁定(如果有)。
下面是该类中的 get 实现 readValueUnderLock 仅当 v 为 null 时调用
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;
}
关于java - ConcurrentHashMap 每次读取时都锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20451203/