Java中的工具类-集合类异常fail safe 与 fail fast
问题
collection接口实现类(arraylist,hashmap中的entry)的迭代过程中面临一个问题:
- 迭代过程中,集合类的元素被修改了会发生什么?
这个问题在java中有两种解决办法:
- fail fast 和 fail safe
Fail Fast 迭代器内部原理
Fail Fast的理念是维护迭代过程中的强一致性
(迭代前后的一致性比较)
ArrayList<Integer> integers = new ArrayList<>();
integers.add(1);
integers.add(2);
integers.add(3);
Iterator<Integer> itr = integers.iterator();
while (itr.hasNext()) {
Integer a = itr.next();
integers.remove(a);
}
这种情况下, 在迭代过程中移除被迭代集合中的元素,会ArrayList内部会抛出ConcurrentModificationException 异常。
内部原理是,ArrayList内部维持了1个变量 modCount,这个变量会增加,当:
-
集合元素增加时
-
集合元素移除、替换时
-
集合元素被重新排序时
在迭代器(iterator)中也维护了一个变量 expectedModCount
这个变量当生成迭代器时被赋值为集合的modCount, 当集合类被修改时,两个变量就不同,此时 会抛出异常。
Fail Safe 迭代器内部原理
Fail Safe的理念是迭代前后的弱一致性
比较。
- 元素被修改后,没有异常抛出。
Fail Safe的实现过程是
public Iterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}
在迭代器中,重新生成一个代理模式下迭代器,集合被整体复制到代理中。