我有以下引发ConcurrentModificationException的代码,因为我在同一列表上使用了两个不同的迭代器,其中一个正在修改列表。因此,第二个迭代器在读取列表时会引发异常,因为其他某个迭代器已经修改了列表。
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知道已被其他迭代器修改了?如何确定其他一些突变了?一种方法可能是跟踪大小,但这不是原因,因为其他迭代器可以替换任何元素。 *list``iterator1``iterator``list
iterator2
list``iterator1``iterator``list
回答此类问题的一种好方法是查看源代码,例如ArrayList的源代码。搜索ConcurrentModificationException。
ConcurrentModificationException
您应该能够说出事情的运作方式是这样的:
根据您的情况,通过iterator1对列表执行删除操作会更改列表的结构操作计数(modCount)。当iterator2要求删除它时,它会看到其expectedModCount,最初接收为0,与列表的当前mod计数不同。
iterator1
modCount
expectedModCount
应当指出,这it.remove是一种特殊情况。当迭代器自行执行删除操作时,它会进行expectedModCount相应调整,以与基础列表保持同步。
it.remove