Java“ConcurrentModificationException"迭代 .next() 时出现运行时错误 [英] Java "ConcurrentModificationException" runtime error when iterating .next()

查看:23
本文介绍了Java“ConcurrentModificationException"迭代 .next() 时出现运行时错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

According to the runtime error message the Exception occurs in the following line;

VirusData v = iteratorVirusDB.next();

<小时>

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


VirusData is a class with a constructor and an overloaded constructor containing specific information about each of the viruses in the database such as;

  • 字符串虚拟名称
  • 字符串 vDefinition

超载

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

iteratorVirusDBVirusDB的.iterator(),如下图:

iteratorVirusDB of type <VirusData> is an .iterator() of VirusDB, as shown bellow:

Iterator<VirusData> iteratorVirusDB = virusDB.iterator();

<小时>

VirusDB 类型的 ArrayList,我在其中存储病毒对象 (此时的名称和定义),以便我可以稍后使用它们.


VirusDB is and ArrayList of type <VirusData> where I store the virus objects (name and def at this point) so that I can use them later.

ArrayList <VirusData> virusDB = new ArrayList<VirusData>();

<小时>

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


And to end with, the error occurs in this method which uses all of the above explained:

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

<小时>

我真的可以提供一些关于如何解决这个问题的帮助和建议,以使程序成功运行.下面是完整的 StackTrace:


I could really do with some help and advice on how to approach this problem in order to get get the program to run successfully. Bellow, the full 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)

推荐答案

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

The obvious explanation is that you have modified the virusDB in between calls. You mustn't modify the vector (except through the Iterator / ListIterator methods) while iterating using an iterator.

这段代码将总是抛出一个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();
    }
}

来自ConcurrentModificationException的文档:

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

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

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

如果您的意图是每次调用该方法时都遍历整个数据库,我建议您这样做

If your intention is to iterate through the entire database each time the method is called, I suggest you do

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

这篇关于Java“ConcurrentModificationException"迭代 .next() 时出现运行时错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆