java - 两个迭代器抛出 ConcurrentModificationException

标签 java iterator concurrentmodification

<分区>

我有以下代码

public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        Arrays.stream("hello how are you".split(" ")).forEach(s -> list.add(s));

        Iterator<String> it = list.iterator();
        ListIterator<String> lit = list.listIterator();

        while (it.hasNext()) {
            String s = it.next();
            if (s.startsWith("a")) {
                it.remove();
            } else {
                System.out.println(s);
            }
        }

        System.out.println(list);

        // {here}

        while (lit.hasNext()) {
            String s = lit.next();
            if (s.startsWith("a")) {
                lit.set("1111" + s);
            } else {
                System.out.println(s);
            }
        }

        System.out.println(list);
}

在这里,在遍历 Iterator 之后,我尝试遍历 ListIterator。但是代码抛出 ConcurrentModificationException。我只是在Iterator 完成后才使用ListIterator 进行修改,但为什么会出现此异常。

当我在 {here} 而不是顶部初始化 ListIterator 时,代码运行完美。

  1. ConcurrentModificationException 是不是当列表被两个线程同时修改时抛出?
  2. 是否初始化迭代器,在列表上创建一个锁?如果是,那么为什么 Java 让我们在一个 Iterator 已经被另一个 Iterator 初始化之后再初始化它?

最佳答案

Isn't ConcurrentModificationException thrown when the list is being modified by two threads simultaneously ?

不一定。 ConcurrentModificationException表示列表在 Iterator 之后已在结构上发生变化(除了 remove 自己的 Iterator 方法)被创建。这可能是由于多个线程使用相同的列表,或者可能是由于尝试从 ArrayList 中删除项目。在 for each 循环中不使用 Iterator .

Does initializing the iterator, create a lock on the list ?

不,没有锁。当 Iterator创建它记录modCountArrayList (列表状态的粗略表示,每次结构更改时都会增加)。如果迭代器检测到对 List 的更改的 modcount 不是由它自己的方法引起的,抛出异常。

由于在实例化和使用第二个迭代器之间对列表进行了结构更改,您从第二个迭代器中获取了异常。

why does Java let us to initialize an Iterator after it has already been initialized by another Iterator?

ArrayList不跟踪它创建的所有迭代器或它们的状态。这样做会使实现变得非常复杂。 modCount方法并不完美而且有点粗糙,但它很简单并且可以识别出许多真正的错误。

关于java - 两个迭代器抛出 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46633396/

相关文章:

java - 如何将 Android 应用程序中的变量插入网页文本字段

java - 编写一个反射(reflect) Java 内置 Iterator 的 ListIterator

java - 来自 Firebase 的 ConcurrentModificationException

java - Android AsyncTask 中的 ConcurrentModificationException

java - ConcurrentModificationException 即使在 foreach 之外更改值

java - 提交时获取请求参数数据

java - tomcat没有这个方法

c# - 有没有一种方法可以将两个单独的迭代器 block 合并为一个?

c++ - 通过迭代器访问 qlist 元素的段错误

java - 如何检查连接池是否被使用