java - FindBugs 对 ConcurrentHashMap 的调用序列可能不是原子的

标签 java findbugs

我不明白为什么 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 仍然提示不是原子的。

它说:

Sequence of calls to concurrenthashmap may not be atomic

将 put 更改为 putIfAbsent,FindBugs 仍然提示。

最佳答案

Findbugs 观察到一对方法调用 map.get(id)map.put(id, obj) 可能不是原子的,这意味着它有可能其他线程在其间修改 map

例如,另一个线程可能会在这两个调用之间记录不同的键 id 映射,然后当第一个线程执行其 map.put() 时,该映射会默默丢失>。由于您费心测试该键最初是否存在映射,因此该结果似乎不太可能是可接受的。

解决此问题的一种方法是使用 ConcurrentHashMap.putIfAbsent() 代替两个调用(不仅仅是代替 put())。

关于java - FindBugs 对 ConcurrentHashMap 的调用序列可能不是原子的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29657960/

相关文章:

java - findbugs可以检测未使用的公共(public)方法吗

java - 如何从 OLSMultipleLinearRegression 获取 T-Stat 和 P-Value

java - 如何使用 GridBagLayout 和 GridLayout 实现最佳对齐?

java - 不正确的延迟初始化

maven-2 - 如何让 Hudson 生成 Findbugs 报告而不会因异常而失败?

java - 这里需要Cloneable吗?

java - 使用驱动程序显示数组中的平均整数

java - @RequestParam 为空(Spring MVC)

按下向上和向下箭头时,Java FX 无法识别 KeyCode.UP 或 KeyCode.Down (MacBook Pro 18 - Mojave 10.14.5)

java - findbugs 性能检测器