ho la seguente classe:Java Singleton sincronizzazione per il multi-thread utilizzando HashMap
public class AggregationController {
private HashMap<String, TreeMap<Integer, String>> messages;
private HashMap<String, Integer> counters;
Boolean buildAggregateReply;
private boolean isAggregationStarted;
private static HashMap<String, AggregationController> instances = new HashMap<String, AggregationController>();
private AggregationController() throws MbException{
messages = new HashMap<String, TreeMap<Integer,String>>();
counters = new HashMap<String, Integer>();
buildAggregateReply = true;
isAggregationStarted = false;
}
public static synchronized AggregationController getInstance(String id) throws MbException{
if(instances.get(id) == null)
instances.put(id, new AggregationController());
return instances.get(id);
}
ho pensato che sarebbe stato sufficiente per evitare l'accesso simultaneo, ma ho ottenuto questo errore:
HashMap.java
checkConcurrentMod
java.util.HashMap$AbstractMapIterator
java.util.ConcurrentModificationException
Unhandled exception in plugin method
java.util.ConcurrentModificationException
I ha 10 thread che usano questa classe e lancia questo errore circa una volta ogni 100.000 chiamate.
Che cosa è sbagliato con questo singleton?
completa analisi dello stack con il codice di cui si vede questa eccezione si verificano? – SMA
Sincronizzate le chiamate sulle mappe all'interno della vostra classe? Forse questi accessi potrebbero causare problemi? – red13
Ho trovato il problema. Una delle funzioni (non scritta qui) stava tentando di accedere allo stesso oggetto rispetto all'istanza get. Queste 2 funzioni erano sincronizzate singolarmente, ma potevano essere chiamate nello stesso momento Per risolvere il problema, l'ho modificato in una ConcurrentHashMap e ho anche migliorato la sincronizzazione utilizzando il blocco con doppio controllo. Ora eseguirò i test tutta la notte e ti faccio sapere se il problema è veramente risolto –