抛出ConcurrentModificationException异常的原因

在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() 方法会在删除当前迭代对象的同时维护索引的一致性。

问题解决方案:

  1. 单线程情况下:调用iterator.remove()方法
    在iterator.remove()方法中,利用expectedModCount = modCount重置了expectedModCount值,使二者的值继续保持相等
  2. 多线程情况下 :
    方案一:iterator遍历过程加同步锁,锁住整个arrayList
    方案二:使用CopyOnWriteArrayList

本篇文章源于 :https://www.cnblogs.com/snowater/p/8024776.html
仅作自我参考使用

你可能感兴趣的:(抛出ConcurrentModificationException异常的原因)