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