synchronized(synchronizedMap)
,真的有必要吗,因为syncedMap始终会确保没有两个线程试图对其进行read/put
操作,Map
那么为什么我们需要synchronize
对该地图本身进行处理呢?非常感谢您的解释。
public class MyClass {
private static Map<String, List<String>> synchronizedMap =
Collections.synchronizedMap(new HashMap<String, List<String>>());
public void doWork(String key) {
List<String> values = null;
while ((values = synchronizedMap.remove(key)) != null) {
//do something with values
}
}
public static void addToMap(String key, String value) {
synchronized (synchronizedMap) {
if (synchronizedMap.containsKey(key)) {
synchronizedMap.get(key).add(value);
}
else {
List<String> valuesList = new ArrayList<String>();
valuesList.add(value);
synchronizedMap.put(key, valuesList);
}
}
}
}
为什么我们需要对其
synchronizemap
本身进行同步?
您可能需要在一个已经同步的集合上进行同步,因为您正在对该集合执行两个操作-在您的示例中,是a containsKey()
然后是a put()
。您试图在调用集合的代码中防止竞争情况。另外,在这种情况下,该块还保护值,以便多个线程可以将其值添加到这些未同步的集合中。synchronized
ArrayList
如果您查看链接到的代码,他们将首先检查键的存在,如果键不存在,则将值放入映射中。您需要防止2个线程的一个重要的生存确认,然后两个人投入的地图。比赛是哪一个将第一名,哪个人将覆盖前一名。
同步的集合可保护自己免受多个线程破坏映射本身的侵害。它不能防止围绕多次调用该映射的逻辑竞争条件。
synchronized (synchronizedMap) {
// test for a key in the map
if (synchronizedMap.containsKey(key)) {
synchronizedMap.get(key).add(value);
} else {
List<String> valuesList = new ArrayList<String>();
valuesList.add(value);
// store a value into the map
synchronizedMap.put(key, valuesList);
}
}
这是ConcurrentMap
接口具有的原因之一putIfAbsent(K key, V value);
。但这并不需要两个操作,所以你可能并不需要围绕它同步。
顺便说一句,我将上面的代码重写为:
synchronized (synchronizedMap) {
// test for a key in the map
List<String> valuesList = synchronizedMap.get(key);
if (valueList == null) {
valuesList = new ArrayList<String>();
// store a value into the map
synchronizedMap.put(key, valuesList);
}
valuesList.add(value);
}
最后,如果地图上的大多数操作synchronized
无论如何都需要位于一个块中,那么您不妨为支付费用,synchronizedMap
而只需HashMap
在synchronized
块中始终使用一个即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句