有关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. MessagePack 新型序列化反序列化方案

    进入在学习redis的时候,在文中看到了关于MessagePack的简介,发现非常有意思,于是就花了点时间大致了解了下. MessagePack介绍: MessagePack is an effici ...

  2. 「LOJ10150」括号配对

    [题目] Hecy 又接了个新任务:BE 处理.BE 中有一类被称为 GBE. 以下是 GBE 的定义: 空表达式是 GBE 如果表达式 A 是 GBE,则 [A] 与 (A) 都是 GBE 如果 A ...

  3. BZOJ 1037 生日聚会 DP

    [ZJOI2008]生日聚会Party Time Limit: 10 Sec Memory Limit: 162 MB Description 今天是hidadz小朋友的生日,她邀请了许多朋友来参加她 ...

  4. Spark Streaming基础概念

    为了更好地理解Spark Streaming 子框架的处理机制,必须得要自己弄清楚这些最基本概念. 1.离散流(Discretized Stream,DStream):这是Spark Streamin ...

  5. sql的padleft

    /* SELECT dbo.fn_PadLeft('8', '0', 6) */ create function fn_PadLeft(@num nvarchar(16),@paddingChar c ...

  6. 【Oracle】表连接三种方式

    表连接的方式有三种分别是:排序合并连接(Sort Merge Join).嵌套循环连接(Nested Loops Join).哈希连接(Hash Join). 1. 排序合并连接(Sort Merge ...

  7. java程序员级别划分

    IT路虽好,却难走.1级   为会基本语法 大学里的JAVA教程 能及格 2级   自己可以写个 俄罗斯方块,扫雷,贪吃蛇, 拼图之类的小游戏 3级   能够进手机游戏CP,SP公司,做手机游戏 或者 ...

  8. python tips:匿名函数lambda

    lambda用于创建匿名函数,下面两种函数定义方式等价. f = lambda x: x + 2 def f(x): return x + 2 立刻执行的匿名函数 (lambda x: print(x ...

  9. eas之导入导出

    // 是否仅导出有数据的区域,该方法对所有的导出生效(默认为false)table.getIOManager().setExpandedOnly(true); 输入KDF 如果你已经有了一个完整的KD ...

  10. Dell R720修改远程管理口的密码

    今天有个客户需要通过远程管理口来查看系统事件日志,但是他们把初始密码改过并且还给忘记了.后来我决定进操作系统(cent os)进行修改.整个过程很简单,进入系统后只需要三个步骤就解决问题了 1.安装软 ...