java ConcurrentModificationException探究
当集合结构被修改,会抛出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); }
运行会抛出异常
java.util.ConcurrentModificationException
如果又想在遍历的时候做删除操作呢? 借肋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
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 <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!=java.util.ArrayList
你还是你同一个名字却是另一个他....
java.util.Arrays.ArrayList并没有实现remove方法,所以也就抛出了UnsupportedOperationException 就不足为其了!
看似简单的问题多想一点就好了!
java ConcurrentModificationException探究的更多相关文章
- Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- Java并发编程:Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- 【转】Java ConcurrentModificationException异常原因和解决方法
原文网址:http://www.cnblogs.com/dolphin0520/p/3933551.html Java ConcurrentModificationException异常原因和解决方法 ...
- 一种隐蔽性较高的Java ConcurrentModificationException异常场景
前言 在使用Iterator遍历容器类的过程中,如果对容器的内容进行增加和删除,就会出现ConcurrentModificationException异常.该异常的分析和解决方案详见博文<Jav ...
- Java ConcurrentModificationException 异常分析与解决方案
Java ConcurrentModificationException 异常分析与解决方案http://www.2cto.com/kf/201403/286536.html java.util.Co ...
- 9、Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- 【转】Java ConcurrentModificationException 异常分析与解决方案--还不错
原文网址:http://www.2cto.com/kf/201403/286536.html 一.单线程 1. 异常情况举例 只要抛出出现异常,可以肯定的是代码一定有错误的地方.先来看看都有哪些情况会 ...
- (转)Java ConcurrentModificationException异常原因和解决方法
转载自:http://www.cnblogs.com/dolphin0520/p/3933551.html 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会 ...
- ConcurrentModificationException探究
modCount ? 在ArrayList,LinkedList,HashMap等等的内部实现增,删,改中我们总能看到modCount的身影,modCount字面意思就是修改次数 // HashMap ...
随机推荐
- [ASE][Daily Scrum]11.24
今天开会总结了一下第一周的进度,讨论了无限地图的访存方法,做了简单的人员调整, Client的包接收分析与服务器通信这块基本上完成了, 之后Jiafan Zhu会开始和Junbei以及Songtao一 ...
- iBoxDB for .NET v1.5发布, 移动NoSQL数据库
iBoxDB for .NET是一个无须安装配置就可以运行的数据库. 拥有非常高效的性能同时能提供事务支持. 可嵌入到应用程序中也可以使用TCP与应用程序进行远程数据交互 使用易用的操作接口,不需要阅 ...
- WPF学习开发客户端软件-任务助手(已上传源码)
本人纯属WPF新手,布局和WPF的开发水平相当欠缺,从个人来说,还是比较喜欢WPF的,有人说WPF是界面加上WINFORM,我不这样认为,WPF与WINFORM主要的不同在于数据绑定. 这个软件虽 ...
- Java面试题(1)
1.编写一个程序,将d:\java 目录下的所有.java 文件复制到d:\jad 目录下,并将原来文件的扩展名从.java 改为.jad. import java.io.File; import j ...
- [WinAPI] API 14 [获取、设置文件属性和时间]
>_< 为了获取文件属性,用户可以使用GetFileAttributes与GetFileAttributesEx函数. GetFileAttributesEx函数除了返回文件属性外,还返回 ...
- 有助于提高你的 Web 开发技能的7个模式库
正如语言风格指南一样,模式库有两个主要用途.首先,是它们提供了一组编码或设计标准,Web 开发团队可以在整个网站中应用,有助于保持一致的编码实践和外观:其次,对于要学习网页设计最佳实践来说是宝贵的财富 ...
- 使用iMovie和Keynote制作App Preview
App Preview是什么 App Preview就是一段15-30秒的短视频,用来展示你的应用的特性.用户界面.交互方式等内容.在App Store你的应用的详细信息页面里,放在原来的截图之前.体 ...
- JAVA学习Swing绝对局部简单学习
package com.swing; import java.awt.Container; import javax.swing.JButton; import javax.swing.JFrame; ...
- Leetcode 257 Binary Tree Paths 二叉树 DFS
找到所有根到叶子的路径 深度优先搜索(DFS), 即二叉树的先序遍历. /** * Definition for a binary tree node. * struct TreeNode { * i ...
- Leetcode 263 Ugly Number 数论 类似质因数分解
Ugly Number的质因数仅为2,3,5 将输入的数分别除以2,3,5直到不能除,看是否为1,为1的是Ugly Number,其他则不是. class Solution { public: boo ...