2017-06-07 2 views
0

Ich habe Grundkenntnisse in Java und arbeiten derzeit auf einem Java-basierten Code.Iterieren über sortierte Treemap: java.util.ConcurrentModificationException

EDIT: Ich habe nicht schreiben den Code

ich über eine sortierte treemap von Event Objekte und bekommen diese Ausnahme bin Iterieren, wenn ich das nächste Element zu bekommen versuche:

java.util.ConcurrentModificationException at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source) at java.util.TreeMap$KeyIterator.next(Unknown Source)

Ich denke, dies sollte auf das Vorhandensein von mehreren Einträgen mit demselben Wert zurückzuführen sein, die durch den Iteratorkomparator zusammengeführt werden (beziehe sich auf diese question, aber ich weiß nicht, wie man die im Komparator verwendeten Schlüssel findet. Das Objekt Event hat viele Parameter (wie ID, Zeit usw.), aber nicht sicher, welcher für den Iterator verwendet wird. Hier

ist der entsprechende Codeabschnitt (Ausnahme im zweiten SimEvent first = fit.next();):

if (future.size() > 0) { 
     List<SimEvent> toRemove = new ArrayList<SimEvent>(); 
     Iterator<SimEvent> fit = future.iterator(); 
     queue_empty = false; 
     SimEvent first = fit.next(); 
     processEvent(first); 
     future.remove(first); 

     fit = future.iterator(); 

     // Check if next events are at same time... 
     boolean trymore = fit.hasNext(); 
     while (trymore) { 
      SimEvent next = fit.next(); 
      if (next.eventTime() == first.eventTime()) { 
       processEvent(next); 
       toRemove.add(next); 
       trymore = fit.hasNext(); 
      } else { 
       trymore = false; 
      } 
     } 

     future.removeAll(toRemove); 

    } else {...} 

EDIT: Die Halle Code von future Klasse:

public class FutureQueue { 

    /** The sorted set. */ 
    private final SortedSet<SimEvent> sortedSet = new TreeSet<SimEvent>(); 

    /** The serial. */ 
    private long serial = 0; 

    /** 
    * Add a new event to the queue. Adding a new event to the queue preserves the temporal order of 
    * the events in the queue. 
     * 
    * @param newEvent The event to be put in the queue. 
    */ 
    public void addEvent(SimEvent newEvent) { 
     newEvent.setSerial(serial++); 
     sortedSet.add(newEvent); 
    } 

    /** 
    * Add a new event to the head of the queue. 
    * 
    * @param newEvent The event to be put in the queue. 
    */ 
    public void addEventFirst(SimEvent newEvent) { 
     newEvent.setSerial(0); 
     sortedSet.add(newEvent); 
    } 

    /** 
    * Returns an iterator to the queue. 
    * 
    * @return the iterator 
    */ 
    public Iterator<SimEvent> iterator() { 
     return sortedSet.iterator(); 
    } 

    /** 
    * Returns the size of this event queue. 
    * 
    * @return the size 
    */ 
    public int size() { 
     return sortedSet.size(); 
    } 

    /** 
    * Removes the event from the queue. 
    * 
    * @param event the event 
    * @return true, if successful 
    */ 
    public boolean remove(SimEvent event) { 
     return sortedSet.remove(event); 
    } 

    /** 
    * Removes all the events from the queue. 
    * 
    * @param events the events 
    * @return true, if successful 
    */ 
    public boolean removeAll(Collection<SimEvent> events) { 
     return sortedSet.removeAll(events); 
    } 


    public void clear() { 
     sortedSet.clear(); 
    } 
} 

Jeder Vorschlag, wie man vorgehen debuggen Sie dieses Problem?

+0

Würdest du bitte den Code der 'future' Klasse teilen? –

+0

Warum verwenden Sie manchmal fit.next() ohne fit.hasNext() zu überprüfen? – user7294900

+0

@VasiliyVlasov: in der Frage bearbeitet bearbeiten – Betty

Antwort

0

BEARBEITET: Dies ist ein häufiger Fehler. Sie können eine Auflistung nicht direkt ändern (Elemente hinzufügen oder entfernen), wenn Sie die Auflistung mit einer Iterator durchlaufen. Die Entfernung muss zum Beispiel über die Iterator selbst erfolgen.

Der richtige Weg, es zu tun, wie folgt (nicht ein vollständiges Beispiel, nur um den Punkt zu veranschaulichen):

Iterator<SimEvent> fit = future.iterator(); 
while (fit.hasNext()) { 
    SimEvent event = fit.next(); 
    processEvent(event); 
    fit.remove(); 
} 

Uhr für andere Threads, die aus der Sammlung hinzufügen kann oder entfernen, während Sie Iterieren durch.

+0

Sorry, ich sehe nicht, wo eine Sammlung verwendet wird (nur in 'removeAll' Methode der' FutureQueue' Klasse)? Die Sache ist, dass dieser Code in Ordnung ist, bevor ich andere Arten von Ereignissen zur Warteschlange hinzufüge. – Betty

+0

Sind Sie sicher, dass Sie den tatsächlichen Code veröffentlicht haben? Entschuldigung für die Frage, aber ich schaue auf den Quellcode von java.util.TreeMap $ PrivateEntryIterator.nextEntry und kann keinen anderen Grund für die Ausnahme sehen. Haben Sie versucht, den Code in einem Debugger auszuführen? – vempo

+0

Ja ist es. Eigentlich arbeite ich an einem Simulator, der von anderen Leuten entwickelt wurde, ich füge andere Arten von Ereignissen zu 'future' an anderer Stelle im Simulator hinzu, indem ich die' addEvent' Methode verwende. Ich führe den Code im Debugger und ich kann sehen, dass 'fit' nächstes Element hat, aber den Fehler bekommen. – Betty

Verwandte Themen