java fail-fast 机制探究
什么是 fail-fast 机制? fail-fast机制在遍历一个集合时,当集合结构被修改,会抛出Concurrent Modification Exception。 fail-fast会在以下两种情况下抛出ConcurrentModificationException (1)单线程环境 集合被创建后,在遍历它的过程中修改了结构。 注意 remove()方法会让expectModcount和modcount 相等,所以是不会抛出这个异常。 (2)多线程环境 当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改。 如下: private static void test0() { List<String> list = new ArrayList<>(); list.add("a1"); list.add("a2"); list.add("a3"); list.add("a4"); list.add("a5"); list.add("a6"); list.add("a7"); list.add("a8"); for (String s : list) { list.remove(s); } System.out.println(list); }
运行会抛出异常
如果又想在遍历的时候做删除操作呢? 借肋iterator,,如下: private static void test1() { List<String> list = new ArrayList<>(); list.add("a1"); list.add("a2"); list.add("a3"); list.add("a4"); list.add("a5"); list.add("a6"); list.add("a7"); list.add("a8"); Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String str = iter.next(); System.out.println(str); //iter.remove(); if (Randoms.random(1, 9) % 2 == 0) { iter.remove(); } } System.out.println(list); }
这里我们并没有用list.remove元素而是iter.reomve,但实际list中的元素已经被删除也没有抛异常,为什么会这样? 调试的时候我们发现iter.reomve执行最终调用的是 ArrayList
所以自然影响了原来的集合。 Iterator被创建之后会建立一个指向原来对象的单链索引表, 当list删除元素里不会影响索引,Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。 我们再看段代码:
private static void test2() { List list2 = Arrays.asList(new String[]{"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8",}); Iterator iter2 = list2.iterator(); while (iter2.hasNext()) { String str = iter2.next(); System.out.println(str); //iter.remove(); if (Randoms.random(1, 9) % 2 == 0) { iter2.remove(); } } System.out.println(list2); }
结果:
为什么呢?感觉跟test1是一样的? 我们查看源码Arrays: public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } /** * @serial include */ private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{...}
发现两个ArrayList并不是同一个类却取了同一个名字:
你还是你同一个名字却是另一个他.... java.util.Arrays.ArrayList并没有实现remove方法,所以也就抛出了UnsupportedOperationException 就不足为其了! 看似简单的问题多想一点就好了!
(编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |