簡體   English   中英

對ConcurrentHashMap的FindBugs調用序列可能不是原子的

[英]FindBugs sequence of calls to ConcurrentHashMap may not be atomic

我不明白為什么FindBug抱怨此代碼

Foo obj = map.get(id);

if(obj == null) {
    obj = new Foo();
    map.put(id, obj);
}

obj.add(someObject);

第二版

Foo tmp = new Foo();
obj = map.putIfAbsent(id, tmp);
if (obj == null)
   obj = tmp

obj.add(someObject);

如果執行第二個版本,則每次都必須創建Foo對象。

Foo obj = map.get(id);

if(obj == null) {
    lock.writeLock().lock();
    try {
        obj = new Foo();
        map.put(id, obj);
    }finally {
        lock.writeLock().unlock();
    }
}

obj.add(someObject);

對於第三版,FindBugs仍然抱怨不是原子的。

它說 :

並發哈希映射的調用順序可能不是原子的

putIfAbsent更改為putIfAbsent ,FindBugs仍然抱怨。

Findbugs觀察到,一對方法調用map.get(id)map.put(id, obj)可能不是原子的,這意味着其他線程可能會在兩者之間修改map

例如,另一個線程可能在這兩個調用之間記錄了不同的鍵id映射,然后當第一個線程執行其map.put()時,該映射將默默丟失。 由於您不願意測試該鍵最初是否存在映射,因此此結果似乎不太可能被接受。

解決此問題的一種方法是使用ConcurrentHashMap.putIfAbsent()代替兩個調用(而不僅僅是put() )。

如果其他線程在評估if ()語句時添加了帶有該鍵的條目,則該線程將覆蓋它。

您需要使用putIfAbsent ,而不是不與地圖否則互動。

暫無
暫無

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

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