Java中的工具类-集合类异常fail safe 与 fail fast

分类: JVM 发布于:

问题

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);
}

在迭代器中,重新生成一个代理模式下迭代器,集合被整体复制到代理中。