并发修改例外

43 java concurrentmodification

我有这段小代码,它给了我并发修改异常.我无法理解为什么我一直得到它,即使我没有看到任何同时进行的修改.

import java.util.*;

public class SomeClass {
    public static void main(String[] args) {
        List<String> s = new ArrayList<>();
        ListIterator<String> it = s.listIterator();

        for (String a : args)
            s.add(a);

        if (it.hasNext())
            String item = it.next();

        System.out.println(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

Pas*_*ent 52

为避免这种情况ConcurrentModificationException,您应该像这样编写代码:

import java.util.*;

public class SomeClass {

    public static void main(String[] args) {
        List<String> s = new ArrayList<String>();

        for(String a : args)
            s.add(a);

        ListIterator<String> it = s.listIterator();    
        if(it.hasNext()) {  
            String item = it.next();   
        }  

        System.out.println(s);

    }
}
Run Code Online (Sandbox Code Playgroud)

A java.util.ListIterator允许您在迭代期间修改列表,但不允许在创建和使用它之间修改列表.


Ste*_*n C 44

我无法理解为什么我一直得到它,即使我没有看到任何同时进行的修改.

在创建迭代器和开始使用迭代器之间,您向要迭代的列表添加了参数.这是一个并发修改.

    ListIterator<String> it = s.listIterator();  

    for (String a : args)
        s.add(a);                    // concurrent modification here

    if (it.hasNext())
        String item = it.next();     // exception thrown here
Run Code Online (Sandbox Code Playgroud)

在完成向列表中添加元素之后创建迭代器:

    for (String a : args)
        s.add(a); 

    ListIterator<String> it = s.listIterator();  
    if (it.hasNext())
        String item = it.next();
Run Code Online (Sandbox Code Playgroud)


leo*_*onm 11

来自JavaDoc:对于ConcurrentModificatoinException:"一个线程修改一个集合而另一个线程迭代它时通常不允许".

它只是意味着如果你仍然有一个打开的迭代器,则不允许修改列表,因为迭代器循环会中断.尝试移动ListIterator<String> it = s.listIterator();到for循环之后.


Yul*_*liy 8

修改基础列表后,不允许继续迭代迭代器.在这里你先添加几个项目之前创建迭代器,然后在添加s之后继续执行a hasNext()和a next(),导致ConcurrentModificationException


jza*_*elo 5

如果上述解决方案无法正常工作.您可以使用旧的for循环来迭代List,同时添加新项.请参阅以下示例:

import java.util.*;

public class SomeClass {
    public static void main(String[] args) {
        ArrayList<AClass> aList = new ArrayList<AClass>(); // we will iterate this


        // this will cause ConcurrentModificationException. 
        // Since we are iterating the list, at the same time modifying it.
        /*for(AClass a: aList){
           aList.add(someMethod(a));
        }*/

        // old fashion for-loop will help
        int limit = aList.size();
        for(int i=0; ctr<limit; ++i){
           AClass a = aList.get(i);
           aList.add(someMethod(a));
        }


    }
}
Run Code Online (Sandbox Code Playgroud)

  • 从现在开始,我将永远不会使用每个循环.使用ListIterator并不简洁,不使用ListIterator会导致此异常.我宁愿在代码中添加更多单词并完成它.老循环永远:p (2认同)