【Java】ConcurrentModificationException是什么?
编程学习日志
2020年11月15日
在使用Java编写代码并进行测试的过程中,我遇到了一个叫做java.util.ConcurrentModificationException的异常。我需要总结一下ConcurrentModificationException是什么,以及应该如何处理它。
ConcurrentModificationException是什么意思?
ConcurrentModificationException的Javadoc中写道如下。
如果对象发生并发修改,并且不允许此类修改的方法检测到了这种情况,将会引发此异常。
一般来说,”fail-first”是用来在重复操作发生更改时立即失败并抛出异常的。也就是说,在重复处理结束之前就会出现异常。
对于每个循环使用了Iterator,虽然不算冗长,但如果在测试中重构为使用Iterator,就可以访问额外的方法,如remove()等。由于remove方法不会引发ConcurrentModificationException,所以即使在循环处理过程中调用也是安全的。
在我的代码中,处理ArrayList的方式存在问题。ArrayList和Iterator在内部都保持着”修改的次数”。由ArrayList的iterator()方法生成的Iterator在使用next()方法等进行遍历时,会检查修改的次数是否存在偏差,如果存在偏差,则会抛出ConcurrentModificationException异常。
在Javadoc的ArrayList中有以下描述:
这个类的iterator和listIterator方法返回的迭代器是快速失败的。在创建迭代器后,如果通过迭代器本身的remove或add方法以外的方式对列表进行了结构性更改,迭代器将抛出ConcurrentModificationException异常。为了避免在并发修改时出现无法预测的行为,迭代器会立即且有效地抛出异常。
通常情况下,由于无法保证异步并发修改的确切保证,因此无法保证迭代器的快速失败行为。快速失败迭代器基于”尽力而为”的原则,会抛出ConcurrentModificationException异常。因此,编写依赖于此异常的程序以确保准确性是错误的。”迭代器的快速失败行为应仅用于检测错误”。
文獻引用
在Java中避免ConcurrentModificationException的类是ConcurrentModificationException。