java - ConcurrentHashMap 每次读取时都锁定?

标签 java concurrenthashmap

我想了解 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/

相关文章:

java - 如何配置 Secor(来自 pinterest)以按一天中的小时对文件进行分区?

Java 7 Unicode 正则表达式 仅制表符和仅空格

java - Android 内存不足异常存储大量字节

java.io.FileNotFoundException : C:\Users\user\AppData\Local\Temp (Access is denied)

java - ConcurrentHashMap JDK 8 何时使用 computeIfPresent

Java数组问题。无法传递值

java - HashMap、LinkedHashMap 和 ConcurrentHashMap 在创建 Map 和基于特定键获取值时的执行成本

java - 使用双重检查锁定,对 volatile ConcurrentHashMap 的 put 是否有 happens-before 保证?

c++ - 如何将 tbb concurrent_hash_map 转换为常规 std::map?

Java ConcurrentHashMap 不是线程安全的..wth?