[英]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.