以下代码是否已正确设置同步调用 synchronizedMap
?
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);
}
}
}
}
据我的理解,在 addToMap()
方法中,我需要同步块来防止另一个线程在我调用 put()
之前调用 remove()
或 containsKey()
方法,但是在 doWork()
方法中,我不需要同步块,因为另一个线程不能在 remove()
方法返回之前进入 addToMap()
中的同步块,因为我最初使用 Collections.synchronizedMap()
创建了 Map。这是正确的吗?还有更好的方法吗?
Collections.synchronizedMap()
,为什么还需要同步块?我不理解第二个观点。 - Bimal Sharmacontains
时没有其他线程会改变其状态,get
也是一样。但是,在contains
和get
之间,另一个线程可能会替换或删除通过contains
检查的元素,因此您的get
结果可能不是您期望的。这就是为什么使用同步块的原因,以保证这两个原子操作之间没有更改。 - Koenigsberg