java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap
您的代碼中可能存在細微的錯誤。
[更新:因為他正在使用map.remove(),所以這種描述并不完全有效。 我第一次錯過了這個事實。 :(感謝問題的作者指出這一點。我將其余部分保留原樣,但改變了主要聲明,說有可能存在錯誤。]
在doWork()中,您可以以線程安全的方式從Map獲取List值。 然而,之后,您在不安全的情況下訪問該列表。 例如,一個線程可能正在使用doWork()中的列表,而另一個線程在addToMap()中調用synchronizedMap.get(key).add(value)。 這兩個訪問不同步。 經驗法則是集合的線程安全保證不會擴展到它們存儲的鍵或值。
你可以通過在地圖中插入一個同步列表來解決這個問題
List valuesList = new ArrayList();
valuesList.add(value);
synchronizedMap.put(key, Collections.synchronizedList(valuesList)); // sync'd list
或者,您可以在doWork()中訪問列表時在地圖上進行同步:
public void doWork(String key) {
List values = null;
while ((values = synchronizedMap.remove(key)) != null) {
synchronized (synchronizedMap) {
//do something with values
}
}
}
最后一個選項會稍微限制并發性,但IMO會更加清晰。
另外,關于ConcurrentHashMap的快速說明。 這是一個非常有用的類,但并不總是適用于同步HashMaps的替代品。 引用其Javadocs,
在依賴于線程安全但不依賴于其同步細節的程序中,此類可與Hashtable完全互操作。
換句話說,putIfAbsent()非常適合原子插入,但不保證在該調用期間地圖的其他部分不會改變; 它只保證原子性。 在您的示例程序中,您依賴于put()s以外的(同步)HashMap的同步詳細信息。
最后一件事。 :)來自Java Concurrency in Practice的這句精彩報價總能幫助我設計調試多線程程序。
對于可由多個線程訪問的每個可變狀態變量,必須在保持相同鎖的情況下執行對該變量的所有訪問。
總結
以上是生活随笔為你收集整理的java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Python语音识别项目笔记] 2矩阵
- 下一篇: [Python语音识别项目笔记] 3so