概述
在Java开发过程中,使用iterator遍历集合的同时对集合进行修改就会出现java.util.ConcurrentModificationException异常。
问题发生原因:
在iterator的next方法中首先调用了checkForComodification方法,该方法会判断modCount是否等于expectedModCount,不等于就会抛出java.util.ConcurrentModificationExcepiton异常。modCount是ArrayList的一个属性,继承自抽象类AbstractList,用于表示ArrayList对象被修改次数。在创建Iterator的时候会将modCount赋值给expectedModCount,在执行next方法时,遇到modCount != expectedModCount方法,导致抛出异常java.util.ConcurrentModificationException。
1 final void checkForComodification() {
2 if (modCount != expectedModCount)
3 throw new ConcurrentModificationException();
4 }
明白了抛出异常的过程,但是为什么要这么做呢?
Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。
Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变。
当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。
问题解决方案:
- 单线程情况下:调用iterator.remove()方法
在iterator.remove()方法中,利用expectedModCount = modCount重置了expectedModCount值,使二者的值继续保持相等 - 多线程情况下 :
方案一:iterator遍历过程加同步锁,锁住整个arrayList
方案二:使用CopyOnWriteArrayList
本篇文章源于 :https://www.cnblogs.com/snowater/p/8024776.html
仅作自我参考使用
最后
以上就是酷炫茉莉为你收集整理的抛出ConcurrentModificationException异常的原因的全部内容,希望文章能够帮你解决抛出ConcurrentModificationException异常的原因所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复