Rac*_*hel 14 java multithreading
我指的是这里提出的问题并使用作者代码示例,现在我的问题是
synchronized(synchronizedMap),是否真的有必要,因为synchronizedMap将始终确保没有两个线程尝试进行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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Gra*_*ray 18
为什么我们需要同步
synchronizemap呢?
您可能需要在已经同步的集合上进行同步,因为您正在对集合执行两个操作 - 在您的示例中,a containsKey(),然后是a put().您正试图在调用集合的代码中防止竞争条件.此外,在这种情况下,块还保护值,以便多个线程可以将它们的值添加到这些未同步的集合中.synchronizedArrayList
如果查看链接的代码,他们首先检查密钥是否存在,然后在密钥不存在时将值放入映射中.您需要防止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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是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);
}
Run Code Online (Sandbox Code Playgroud)
最后,如果地图上的大多数操作synchronized无论如何都需要在一个块中,你也可以不用付钱synchronizedMap而只是使用一个HashMap总是在synchronized块里面.