迭代时出现Java"ConcurrentModificationException"运行时错误.next()

Car*_*los 9 java iterator runtime-error exception arraylist

根据运行时错误消息,异常发生在以下行中;

VirusData v = iteratorVirusDB.next();
Run Code Online (Sandbox Code Playgroud)

VirusData 是一个带有构造函数和重载构造函数的类,其中包含有关数据库中每种病毒的特定信息,例如;

  • 字符串vName
  • 字符串vDefinition

重载

  • 具有标记化定义的数组(以xLength分组分隔)
  • 带LCS令牌的数组
  • 漂浮等级

iteratorVirusDBtype <VirusData>是.iterator()VirusDB,如下所示:

Iterator<VirusData> iteratorVirusDB = virusDB.iterator();
Run Code Online (Sandbox Code Playgroud)

VirusDBis和ArrayList的类型<VirusData>,我存储病毒对象(此时名称和def),以便我以后可以使用它们.

ArrayList <VirusData> virusDB = new ArrayList<VirusData>();
Run Code Online (Sandbox Code Playgroud)

最后,在使用上述所有解释的方法中发生错误:

private void selectDabataseMouseClicked(java.awt.event.MouseEvent evt) {
    while(iteratorVirusDB.hasNext()) {
        VirusData v = iteratorVirusDB.next();               //ERROR LINE
        String vSig = v.signature;                              
        v.tokens = tokenize.raw(vSig, true, tLength);
        ...
     }
     ...
}
Run Code Online (Sandbox Code Playgroud)

我可以真正做一些帮助和建议,如何解决这个问题,以使程序成功运行.Bellow,完整的StackTrace:

run:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at project_clean.Main.selectDabataseMouseClicked(Main.java:275)
        at project_clean.Main.access$100(Main.java:11)
        at project_clean.Main$2.mouseClicked(Main.java:76)
        at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
        at java.awt.Component.processMouseEvent(Component.java:6270)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4247)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Run Code Online (Sandbox Code Playgroud)

aio*_*obe 11

显而易见的解释是你已经修改了virusDB两次通话.在使用迭代器进行迭代时,不得修改向量(通过Iterator/ ListIterator方法除外).

这段代码将始终抛出ConcurrentModificationException:

import java.util.*;

class VirusData {
}

public class Test {

    public static void main(String[] args) {

        List<VirusData> list = new ArrayList<VirusData>() {{
            add(new VirusData());
            add(new VirusData());
            add(new VirusData());
        }};

        Iterator<VirusData> iterator = list.iterator();

        iterator.next();

        list.remove(0);
        VirusData s = iterator.next();
    }
}
Run Code Online (Sandbox Code Playgroud)

来自以下文件ConcurrentModificationException:

例如,一个线程通常不允许修改Collection而另一个线程正在迭代它.通常,在这些情况下,迭代的结果是不确定的.如果检测到此行为,某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常.执行此操作的迭代器称为失败快速迭代器,因为它们快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险.

请注意,此异常并不总是表示某个对象已被另一个线程同时修改.如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常.例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常.

如果您打算每次调用该方法时遍历整个数据库,我建议您这样做

private void selectDabataseMouseClicked(java.awt.event.MouseEvent evt) {
    Iterator<VirusData> iteratorVirusDB = virusDB.iterator();
    while(iteratorVirusDB.hasNext()) {
        VirusData v = iteratorVirusDB.next();
        String vSig = v.signature;                              
Run Code Online (Sandbox Code Playgroud)

  • 列表并不关心内容对象本身是否在变化,它只关心结构修改,例如添加和删除元素,以及可能用另一个元素替换元素(`set(...)` - 仅 - 这些是列表**的修改**.当然,如果你的程序是多线程的,你通常不应该在另一个线程中使用它们时修改你的对象,所以使用适当的同步. (2认同)