java集合中的fail-fast与fail-safe两种模式

java中的集合有线程安全的j.u.c包下的集合与java.util下面的线程不安全的集合。针对这两种集合有fail-fast与fail-safe两种模式。

fail-fast表示快速失败,失败即立即返回失败。

fail-safe表示安全跳过,不会抛异常中断。

线程不安全的集合在获取迭代器迭代的时候,如果集合中的元素发生了变化,例如新增或者删除,由于线程不安全,迭代器在next时会直接抛出concurrentModificationException,通过内部的一个modCount判断是否等于expectedModCount来进行比较。从而马上就抛异常退出。而线程安全的集合在迭代时首先会复制一份集合中的内容,然后迭代的过程中由于都是通过副本来迭代的,所以对迭代没有影响,但是数据可能并不会立马反映在迭代过程中。

1.fail-fast案例

public class TestFailFast {

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);

        Iterator<Integer> iterator = list.iterator();

        while (iterator.hasNext()){
            System.out.println(iterator.next());
            list.add(4);
        }

    }
}

结果

1
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
	at java.util.ArrayList$Itr.next(ArrayList.java:861)
	at com.example.demo.fail.TestFailFast.main(TestFailFast.java:25)

fail-safe案例

public class TestFailSafe {

    public static void main(String[] args) {

        CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList();

        copyOnWriteArrayList.add(1);
        copyOnWriteArrayList.add(2);

        Iterator iterator = copyOnWriteArrayList.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
            copyOnWriteArrayList.add(3);
        }
    }
}

结果

1
2

可以看到j.u.c包下的线程安全的集合在迭代的过程中,如果集合的元素发生了修改,并不会抛异常,这就是fail-safe机制,但是缺点就是元素的修改并不会立刻反映出来,适用于读多写少的场景。

经验分享 程序员 微信小程序 职场和发展