簡體   English   中英

為什么我們需要鎖定 Hashtable/ConcurrentHashMap 的 put 方法?

[英]Why do we need lock in the put methods of Hashtable/ConcurrentHashMap?

我試圖了解 Hashtable/Concurrent HashMap 在多線程環境中的功能。 我不明白為什么要同步哈希表的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的行(在循環所有條目並且沒有找到帶有鍵的條目之后)會發生什么? 可能會發生不好的事情,例如,對於同一個鍵,字段count (條目數)將增加兩次。

例如,如果有多個線程試圖為特定鍵設置值,我們是否需要使用鎖,為什么我們不能在沒有鎖的情況下執行操作?

鎖確保哈希表一次僅由一個線程更新。 如果同時調用 2 個 puts,則可能有 2 個 puts 嘗試同時添加相同的鍵和值,這會導致錯誤(Hashtable.put 是 UPSERT 而不是 UPDATE)。 鎖定阻止這種情況發生,因為第一個線程添加了一個鍵,第二個線程添加了第二個鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM