Java中的迭代器如何知道何时引发ConcurrentModification异常 [英] How does an Iterator in Java know when to throw ConcurrentModification Exception

查看:99
本文介绍了Java中的迭代器如何知道何时引发ConcurrentModification异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码引发ConcurrentModificationException,因为我在同一列表上使用了两个不同的迭代器,其中一个正在修改列表。因此,第二个迭代器在读取列表时会抛出异常,因为其他某个迭代器已经修改了列表。

I have the following code which throws ConcurrentModificationException because I am using two different iterators on the same list and one of them is modifying the list. So, the second iterator throws the exception when reading the list because some other iterator has modified the list.

    List<Integer> list = new ArrayList<>();

    populate(list);//A method that adds integers to list

    ListIterator<Integer> iterator1 = list.listIterator();
    ListIterator<Integer> iterator2 = list.listIterator();

    while (iterator1.hasNext()) {
        if(iterator1.next() < 5)
            iterator1.remove();
    }

    while (iterator2.hasNext()){
        if(iterator2.next() < 5) {
         //Call handler   
        }
    }

我的问题是 iterator2 内部了解 如果列表如果尚未到达 iterator1 ?如何确定其他迭代器列表进行了突变?一种方法可能是跟踪大小,但这不是原因,因为其他迭代器可以替换任何元素。

My question is how does iterator2 know internally that the list has has been modified by some other iterator if it has not reached an element which is yet removed by iterator1? How does it figure out that some other iterator has mutated the list? One way could be keep track of size but that can't be the reason since some other iterator can just replace any element.

推荐答案

回答此类问题的一种好方法是查看源代码,例如 ArrayList的源代码。搜索 ConcurrentModificationException

A good way to answer questions like this is to look at the source code, for example the source code for ArrayList. Search for ConcurrentModificationException.

您应该可以说事情像这样工作:

You should be able to tell that things work rather like this:


  • 集合对象的修改计数从零开始,并在发生添加或删除或类似操作时增加。

  • 创建迭代器对象时,我们会将集合的当前修改计数存储在迭代器中。

  • 每次使用迭代器时,它都会根据集合的mod计数检查集合的mod计数。迭代器在创建时获得。如果这些值不同,则会引发异常。

在您的情况下,请删除 iterator1执行的操作更改列表的结构操作计数( modCount )。当要求删除 iterator2 时,它会看到其 expectedModCount ,最初收到的是0,与当前mod不同

In your case, remove operations performed by iterator1 on the list change the structural operation count (modCount) of the list. When iterator2 is asked to remove, it sees its expectedModCount, which it received initially as 0, differing from the current mod count of the list.

应注意, it.remove 是特例。当迭代器自行执行删除操作时,其 expectedModCount 会进行相应调整,以与基础列表保持同步。

It should be noted that it.remove is a special case. When an iterator does a remove itself, its expectedModCount adjusts accordingly, to keep in sync with the underlying list.

这篇关于Java中的迭代器如何知道何时引发ConcurrentModification异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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