迭代排序树图:java.util.ConcurrentModificationException

iterating over sorted treemap: java.util.ConcurrentModificationException

我有 Java 的基础知识,目前正在研究基于 Java 的代码。

编辑:我没有写代码

我正在遍历 Event 个对象的排序树图,并在尝试获取下一个元素时遇到此异常:

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

我认为这应该是由于迭代器比较器合并了具有相同值的多个条目(参考这个question,但我不知道如何找到使用的键在比较器中。对象 Event 有许多参数(如 id、时间等)但不确定迭代器使用哪个参数。

这里是相关的代码部分(第二个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 {...}

编辑:future class 的大厅代码:

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();
    }
}

关于如何继续调试这个问题有什么建议吗?

已编辑: 这是一个常见的错误。当使用 Iterator 遍历集合时,您不能直接修改集合(添加或删除元素)。例如,删除必须通过 Iterator 本身完成。

正确的做法如下(不是一个完整的例子,只是为了说明问题):

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

当您遍历集合时,注意可能添加到集合或从集合中删除的其他线程。