有关java.util.ConcurrentModificationException


java doc对这个类的定义:

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. 



For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator
implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly,
rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future. 





Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the
object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception. 





Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

 产生这个异常的原因:并发改动对象,而对象不支持并发改动。

比較常见的是多线程并发,或者单线程遍历集合的时候同一时候改动集合元素。

比方:
package com.doctor.java8;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; /**
* This program crashes by throwing java.util.ConcurrentModificationException. Why? Because the
* iterators of ArrayList are fail-fast; it fails by throwing ConcurrentModificationException if it detects that
* the underlying container has changed when it is iterating over the elements in the container. This behavior
* is useful in concurrent contexts when one thread modifies the underlying container when another thread is
* iterating over the elements of the container.
*
* @author sdcuike
*
* Created on 2016年3月6日 上午10:24:21
*/
public class ModifyingList { /**
* @param args
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) {
System.out.println(iterator.next());
list.add("three");
} // one
// Exception in thread "main" java.util.ConcurrentModificationException
// at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
// at java.util.ArrayList$Itr.next(ArrayList.java:851)
// at com.doctor.java8.ModifyingList.main(ModifyingList.java:24) } }

CopyOnWriteArrayList

既然普通集合的iterators是fail-fast的即不支持訪问同一时候改动的场景。那我们用并发容器CopyOnWriteArrayList。


package com.doctor.java8;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; /**
* Modifying CopyOnWriteArrayList
*
* Observe that the element “four” added three times is not printed as part of the output. This is because
* the iterator still has access to the original (unmodified) container that had three elements. If you create a
* new iterator and access the elements, you will find that new elements have been added to aList.
*
* @author sdcuike
*
* Created on 2016年3月6日 上午10:32:39
*/
public class ModifyingCopyOnWriteArrayList { /**
* @param args
*/
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
list.add("one");
list.add("two");
list.add("three"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) {
System.out.println(iterator.next());
list.add("four");
}
// one
// two
// three
System.out.println("============");
iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// one
// two
// three
// four
// four
// four } }

java.util.concurrent.CopyOnWriteArrayList<E>

A thread-safe variant of java.util.ArrayList in which all mutative operations (add,set, and so on) are implemented by making a fresh copy of
the underlying array.

当对CopyOnWriteArrayList调用改动数据操作方法的时候。会copy一份新的内部数组结构,而对原来的内部数组结构没影响。

假设要訪问新的数据,我们必须又一次获取底层新的数组结构的iterator(见上面的程序)。

有关java.util.ConcurrentModificationException的更多相关文章

  1. java.util.ConcurrentModificationException 解决办法(转载)

    今天在项目的中有一个需求,需要在一个Set类型的集合中删除满足条件的对象,这时想当然地想到直接调用Set的remove(Object o)方法将指定的对象删除即可,测试代码:   public cla ...

  2. java.util.ConcurrentModificationException --map

    key:3-key key:/v1.02-key Exception in thread "main" java.util.ConcurrentModificationExcept ...

  3. 偶遇到 java.util.ConcurrentModificationException 的异常

    今天在调试程序 遇到了如此问题 贴上代码来看看稍后分析 List<String> list = null;boolean isUpdate = false;try { list = JSO ...

  4. 对ArrayList操作时报错java.util.ConcurrentModificationException null

    用iterator遍历集合时要注意的地方:不可以对iterator相关的地方做添加或删除操作.否则会报java.util.ConcurrentModificationException 例如如下代码: ...

  5. LinkedList - java.util.ConcurrentModificationException

    package com.test.io; import java.io.BufferedReader; import java.io.FileNotFoundException; import jav ...

  6. java.util.ConcurrentModificationException 解决办法

    在使用iterator.hasNext()操作迭代器的时候,如果此时迭代的对象发生改变,比如插入了新数据,或者有数据被删除. 则使用会报以下异常:Java.util.ConcurrentModific ...

  7. Iterator之java.util.ConcurrentModificationException

    在运行以下代码时,会报java.util.ConcurrentModificationException异常, public class Demo { public static void main( ...

  8. java.util.ConcurrentModificationException 解决办法(转)

    今天在项目的中有一个需求,需要在一个Set类型的集合中删除满足条件的对象,这时想当然地想到直接调用Set的remove(Object o)方法将指定的对象删除即可,测试代码:   public cla ...

  9. java集合--java.util.ConcurrentModificationException异常

    ConcurrentModificationException 异常:并发修改异常,当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常.一个线程对collection集合迭代,另一个线程对Co ...

  10. list删除操作 java.util.ConcurrentModificationException

    首先大家先看一段代码: public static void main(String[] args) { List<String> listStr = new ArrayList<S ...

随机推荐

  1. 图的最短路径Dijkstra

    #include <stdio.h> #include <string.h> #include <vector> #include <queue> #i ...

  2. 利用 Puppet 实现自动化管理配置 Linux 计算机集群

    随着虚拟化和云计算技术的兴起,计算机集群的自动化管理和配置成为了数据中心运维管理的热点.对于 IaaS.Paas.Saas 来说,随着业务需求的提升,后台计算机集群的数量也会线性增加.对于数据中心的运 ...

  3. MAC软连接

    在mac上不设置环境变量有的时候也可以直接就访问到了某些文件.这个是为什么呢?答案是用了软连接. 1 查看加载文件 可以使用cat命令查看paths文件 cat etc/paths /usr/loca ...

  4. 最近积累的JS 东西,分享一下

    js 关闭页面 var browserName=navigator.appName; if (browserName=="Netscape") { window.open('',' ...

  5. Jenkins自动化部署.net程序

    一.安装Jenkins 百度上一大堆就不做说明了. 二.构建.net前的准备 1.安装MSBUILD.EXE插件 1.1.进去jenkins->系统管理->插件管理 1.2.配置MSBUI ...

  6. 【MySQL】通信协议

    1.TCP/IP(Transmission Control Protocol/Internet Protocol) 该通信协议套件用于连接 Internet 上的主机.在 Linux 操作系统中,TC ...

  7. Visual Studio UI Automation 学习(一)

    这几天需要研究自动化测试工具,因为团队开发使用visual studio,所以需要研究一下Visual studio自带的框架. 刚开始安装的时候,没有选自定义安装,所以安装完成后没有找到UI Aut ...

  8. Eclipse之向前快进,向后快退

    在已经写好的代码上进行修改,存在代码快需要向前快进,向后快退的情况. 选中代码块,然后右击,有Shift Right, Shift Left

  9. C++程序设计实验安排

    2016-2017第二学期C++程序设计的实验时间与地点安排如下表,请大家根据时间按时来上机实验.另外,因为原来安排在4.1的实验因为调休补周一的课,因此挪至周五.另外第4次周六的课,考虑有一些同学有 ...

  10. BZOJ 1106: [POI2007]立方体大作战tet 树状数组 + 贪心

    Description 一个叫做立方体大作战的游戏风靡整个Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规 则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置.这些元素拥有n ...