Ich habe eine Liste namens synchronizedMap
, auf die ich in meiner Funktion doMapOperation
synchronisiere. In dieser Funktion muss ich Elemente zu einer Map hinzufügen/entfernen und auf diesen Objekten aufwendige Operationen ausführen. Ich weiß, dass ich keine teure Operation in einem synchronisierten Block aufrufen möchte, aber ich weiß nicht, wie ich sicherstellen kann, dass die Map konsistent ist, während ich diese Operationen durchführe. Wie mache ich das am besten?
Das ist mein initiales Layout, von dem ich sicher bin, dass es falsch ist, weil man teure Operationen in einem synchronisierten Block vermeiden möchte:
public void doMapOperation(Object key1, Object key2) {
synchronized (synchronizedMap) {
// Entfernen von key1, wenn es vorhanden ist.
if (synchronizedMap.containsKey(key1)) {
Object value = synchronizedMap.get(key1);
value.doExpensiveOperation(); // Sollte nicht im synchronisierten Block sein.
synchronizedMap.remove(key1);
}
// Hinzufügen von key2, wenn nötig.
Object value = synchronizedMap.get(key2);
if (value == null) {
Object value = new Object();
synchronizedMap.put(key2, value);
}
value.doOtherExpensiveOperation(); // Sollte nicht im synchronisierten Block sein.
} // Ende der Synchronisation.
}
Als Fortführung dieser Frage: Wie würden Sie dies in einer Schleife tun?
public void doMapOperation(Object... keys) {
synchronized (synchronizedMap) {
// Durchlaufen der Keys und Entfernen von ihnen.
for (Object key : keys) {
// Überprüfen, ob die Map den Key hat, entfernen, wenn der Key existiert, hinzufügen, wenn der Key nicht existiert.
if (synchronizedMap.containsKey(key)) {
Object value = synchronizedMap.get(key);
value.doExpensiveOperation(); // Sollte hier nicht sein.
synchronizedMap.remove(key);
} else {
Object value = new Object();
value.doAnotherExpensiveOperation(); // Sollte nicht hier sein.
synchronizedMap.put(key, value);
}
}
} // Ende des Synchronisationsblocks.
}
Vielen Dank für die Hilfe.