开发者

Java "ConcurrentModificationException" runtime error when iterating .next() [duplicate]

This question already has answers here: Iterating t开发者_如何学编程hrough a Collection, avoiding ConcurrentModificationException when removing objects in a loop (31 answers) Closed 3 years ago.

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

VirusData v = iteratorVirusDB.next();

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

  • String vName
  • String vDefinition

Overloaded with

  • Array with Tokenized definition (separated in groups of xLength)
  • Array with LCS Tokens
  • Float with a grade

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

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

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

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)


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.

This snippet of code will always throw a 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();
    }
}

From the documentation of ConcurrentModificationException:

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.

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;                              


The concurrent modification exception occurs when you are modifying it while iterating over it at the same time. So check your code if you are modifying the list and it happens while you are iterating over it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜