![](/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.