[英]Findbugs - Sequence of calls to java.util.concurrent.ConcurrentHashMap may not be atomic
[英]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.