java - 为什么Hashtable/ConcurrentHashMap的put方法需要锁?

标签 java concurrency

我试图了解 Hashtable/Concurrent HashMap 在多线程环境中的功能。我不明白为什么要使 hashtable 的 put 方法同步。

例如,如果有多个线程尝试为特定键设置值,我们是否需要使用锁,为什么我们不能在没有锁的情况下执行操作?最坏的情况是,线程会覆盖彼此的数据,这在技术上对我来说似乎是正确的。

我在这里缺少什么?为什么我们需要锁?

最佳答案

以下是 Hashtable.put (JDK 11) 的代码:

public synchronized V put(K key, V value) {
    // Make sure the value is not null
    if (value == null) {
        throw new NullPointerException();
    }

    // Makes sure the key is not already in the hashtable.
    Entry<?,?> tab[] = table;
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    @SuppressWarnings("unchecked")
    Entry<K,V> entry = (Entry<K,V>)tab[index];
    for(; entry != null ; entry = entry.next) {
        if ((entry.hash == hash) && entry.key.equals(key)) {
            V old = entry.value;
            entry.value = value;
            return old;
        }
    }

    addEntry(hash, key, value, index);
    return null;
}

假设它没有同步,如果两个线程在同一个键上调用 put,并且它们到达调用 addEntry 的行(在循环所有条目并没有找到带 key 的)?可能会发生不好的事情,例如,对于同一个键,字段count(条目数)将增加两倍。

关于java - 为什么Hashtable/ConcurrentHashMap的put方法需要锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64065926/

相关文章:

go - 我可以调整缓冲 channel 的大小吗?

java - 调试器无法访问包含页面中的父页面变量

ruby - 是否有适用于 Ruby 的异步日志记录库?

asynchronous - Clojure 交换!原子并行执行

java - 可运行的子类,普通的父类(super class),如何运行子类?

java - 带有 lambda 的 foreach 是否容易出现商品化错误

java - Swing 中的内联编辑组件

Java CDI : How to change producers at runtime using qualifiers with multiple values?

java - 在经常访问的家庭 Activity 中初始化 'MobileAds.initialize'?

java - <set> 中的属性无效 : "null" in new ArrayList at JSP