博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java ConcurrentModificationException探究
阅读量:6627 次
发布时间:2019-06-25

本文共 2585 字,大约阅读时间需要 8 分钟。

当集合结构被修改,会抛出Concurrent Modification Exception。 fail-fast会在以下两种情况下抛出ConcurrentModificationException

(1)单线程环境 集合被创建后,在遍历它的过程中修改了结构。  

  注意 remove()方法会让expectModcount和modcount 相等,所以是不会抛出这个异常。

(2)多线程环境 当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改。

如下:

private static void test0() {        List
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); }

 

运行会抛出异常

java.util.ConcurrentModificationException

如果又想在遍历的时候做删除操作呢? 借肋iterator,如下:

private static void test1() {        List
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
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

public E remove(int index)

所以自然影响了原来的集合。

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

 

结果:

会抛出异常java.lang.UnsupportedOperationException

为什么呢?感觉跟test1是一样的?

我们查看源码Arrays:

public static 
List
asList(T... a) { return new ArrayList<>(a); } /** * @serial include */ private static class ArrayList
extends AbstractList
implements RandomAccess, java.io.Serializable{...}

 

发现两个ArrayList并不是同一个类却取了同一个名字:

java.util.Arrays.ArrayList!=java.util.ArrayList

你还是你同一个名字却是另一个他....

java.util.Arrays.ArrayList并没有实现remove方法,所以也就抛出了UnsupportedOperationException 就不足为其了!

看似简单的问题多想一点就好了!

 

转载于:https://www.cnblogs.com/tankaixiong/p/6007093.html

你可能感兴趣的文章
如何获取有性能问题的SQL
查看>>
CAS 单点登录 服务器整合
查看>>
根据网址获取图片
查看>>
Java语言简介
查看>>
C# 将内存中的datatable数据导出为Excel(方法一,以文件流方式导出)
查看>>
java条件判断语句switch小结
查看>>
js篇之对象数据属性与存取器属性
查看>>
金山实习总结
查看>>
Android中Webview使用javascript调用事先定义好的Java函数
查看>>
Caching in ASP.NET MVC
查看>>
黑马程序员-C语言常见的一些错误
查看>>
安装虚拟机
查看>>
编解码(编码解码)常识
查看>>
转载泡泡机器人——IMU预积分总结与公式推导1
查看>>
2013 Regional 总结 与 acm 感想 由新手到菜鸟
查看>>
canvas知识点总结3
查看>>
[设计模式]<<设计模式之禅>>之关于单一职责原则
查看>>
单链表
查看>>
MssqlOnLinux高可用--集群故障转移【4】
查看>>
Microsoft Soft SQL Server 大数据----分区表性能测试
查看>>