Я хотел бы реализовать вариант коллекции «Карта наборов», к которому будут постоянно обращаться несколько потоков.Мне интересно, достаточна ли выполняемая мной синхронизация, чтобы гарантировать, что никаких проблем не возникнет.
Итак, учитывая следующий код, где Map, HashMap и Set являются реализациями Java, а Key и Value являются произвольнымиОбъекты:
public class MapOfSets {
private Map<Key, Set<Value>> map;
public MapOfLists() {
map = Collections.synchronizedMap(new HashMap<Key, Set<Value>());
}
//adds value to the set mapped to key
public void add(Key key, Value value) {
Set<Value> old = map.get(key);
//if no previous set exists on this key, create it and add value to it
if(old == null) {
old = new Set<Value>();
old.add(value);
map.put(old);
}
//otherwise simply insert the value to the existing set
else {
old.add(value);
}
}
//similar to add
public void remove(Key key, Value value) {...}
//perform some operation on all elements in the set mapped to key
public void foo(Key key) {
Set<Value> set = map.get(key);
for(Value v : set)
v.bar();
}
}
Идея заключается в том, что, поскольку я синхронизировал саму карту, методы get () и put () должны быть атомарными, верно?Поэтому не нужно выполнять дополнительную синхронизацию на карте или наборах, содержащихся в ней.Так будет ли это работать?
В качестве альтернативы приведенный выше код будет иметь преимущество перед другим возможным решением для синхронизации:
public class MapOfSets {
private Map<Key, Set<Value>> map;
public MapOfLists() {
map = new HashMap<Key, Set<Value>();
}
public synchronized void add(Key key, Value value) {
Set<Value> old = map.get(key);
//if no previous set exists on this key, create it and add value to it
if(old == null) {
old = new Set<Value>();
old.add(value);
map.put(old);
}
//otherwise simply insert the value to the existing set
else {
old.add(value);
}
}
//similar to add
public synchronized void remove(Key key, Value value) {...}
//perform some operation on all elements in the set mapped to key
public synchronized void foo(Key key) {
Set<Value> set = map.get(key);
for(Value v : set)
v.bar();
}
}
Где я оставляю структуры данных несинхронизированными, а вместо этого синхронизирую все возможные общедоступные методы.Так какие из них будут работать, а какие лучше?