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机制,但是缺点就是元素的修改并不会立刻反映出来,适用于读多写少的场景。
下一篇:
Unity的判空逻辑以及优化思路