![](/img/trans.png)
[英]Findbugs - Sequence of calls to java.util.concurrent.ConcurrentHashMap may not be atomic
[英]How to resolve the findbug Sequence of calls to java.util.concurrent.ConcurrentHashMap may not be atomic
嗨,当我运行以下代码时,在我的项目中找到错误时,我收到了错误“对java.util.concurrent.ConcurrentHashMap的调用序列可能不是原子的”。
public static final ConcurrentHashMap<String,Vector<Person>> personTypeMap = new ConcurrentHashMap<String, Vector<Person>>();
private static void setDefaultPersonGroup() {
PersonDao crud = PersonDao.getInstance();
List<Person> personDBList = crud.retrieveAll();
for (Person person : personDBList) {
Vector<Person> personTypeCollection = personTypeMap.get(person
.getGroupId());
if (personTypeCollection == null) {
personTypeCollection = new Vector<Person>();
personTypeMap.put(personTypeCollection.getGroupId(),
personTypeCollection);
}
personTypeCollection.add(person);
}
}
我在personTypeMap.put(personTypeCollection.getGroupId(),personTypeCollection)行遇到此问题;
谁能帮助我解决问题。
您正在执行哪些复合操作?
Map
是否包含键的向量 Vector
因此,这是一个两步操作,很复杂,因此不安全。
他们为什么不安全?
因为它们不是原子的 。 考虑一下您有两个线程的情况。
考虑以下时间轴:
Thread 1 --- checks for == null -> true puts a new Vector
Thread 2 --- checks for ==null -> true puts a new Vector
在ConcurrentHashMap
上使用putIfAbsent()
方法,为您要执行的操作提供原子解决方案。
ConcurrentHashMap#putIfAbsent()
参考文献:
该findbugs消息告诉您在多线程访问的情况下不安全:
您正在从personTypeMap
获取某些personTypeMap
,检查其是否为null
,然后在这种情况下放入一个新条目。 这里有两个线程可以轻松地交织:
线程1:从地图获取
线程2:从地图获取
线程1:检查返回的值是否为空
线程1:放置新值
线程2:检查返回的值是否为空
线程2:放置新值
(仅作为示例;实际上,顺序不是给定的,关键是两个线程都为null
然后对其执行操作)
您应该创建一个新条目,然后调用personTypeMap.putIfAbsent()
因为这样可以保证原子性。
就您而言,您的代码应如下所示:
public static final ConcurrentHashMap<String,Vector<Person>> personTypeMap = new ConcurrentHashMap<String, Vector<Person>>();
private static void setDefaultPersonGroup() {
PersonDao crud = PersonDao.getInstance();
List<Person> personDBList = crud.retrieveAll();
for (Person person : personDBList) {
// the putIfAbsent works in the same way of your
//previous code, but in atomic way
Vector<Person> personTypeCollection = personTypeMap.putIfAbsent(person
.getGroupId());
personTypeCollection.add(person);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.