简体   繁体   English

遍历排序的树图:java.util.ConcurrentModificationException

[英]iterating over sorted treemap: java.util.ConcurrentModificationException

I have basic knowledge in Java and working currently on a Java based code. 我具有Java的基本知识,目前正在研究基于Java的代码。

EDIT: I didn't write the code 编辑:我没有写代码

I am iterating over a sorted treemap of Event Objects and getting this exception when I am trying to get the next element: 我正在遍历Event对象的排序树图,并在尝试获取下一个元素时遇到此异常:

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

I think this should be due to the existence of mutiple entries with same value that are merged by the iterator comparator (be refering to this question , but I don't know how to find the keys used in the comparator. The object Event has many parameters (like id, time, etc)but not sure which one is used for the iterator. 我认为这应该是由于存在迭代器比较器合并的具有相同值的多个条目(参考此问题 ,但我不知道如何找到比较器中使用的键。对象Event有很多参数(例如ID,时间等),但不确定用于迭代器的参数。

Here is the related code portion (exception in the second SimEvent first = fit.next(); ): 这是相关的代码部分(第二个SimEvent first = fit.next();例外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: The hall code of future class: 编辑: future课程的大厅代码:

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

Any suggestion on how to proceed to debug this problem? 关于如何继续调试此问题的任何建议?

EDITED: This is a common mistake. 编辑:这是一个常见错误。 You cannot modify a collection directly (add or remove elements) when iterating through the collection using an Iterator . 使用Iterator遍历集合时,不能直接修改集合(添加或删除元素)。 Removal, for example, must be done via the Iterator itself. 例如,删除必须通过Iterator本身完成。

The correct way to do it is as follows (not a complete example, just to illustrate the point): 正确的方法如下(不是完整的示例,只是为了说明这一点):

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

Watch for other threads that might add to or remove from the collection while you are iterating through it. 在遍历集合时,请注意可能会添加到集合中或从集合中删除的其他线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM