ConcurrentModificationException 快速失败迭代器异常案例及四种解决
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
by codebrother v1.0
1
ConcurrentModificationException 快速失败迭代器
异常案例及四种解决方案
异常案例介绍:
基于 C/S 的 JFrame 界面,使用 JPanel 模拟管道,每当生成一个
管道,便添加到 List 中,符合某种条件的时候,删除对应的管道。
算法:遍历 List,一旦元素符合便移除,这样剩下的便是符合条
件的管道;
运行结果报异常:ConcurrentModificationException
查询 JDK 帮助文档,才发现这种现象属于“快速失败迭代器”;
意思是遍历集合的时候,不允许对集合做更改。
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
2
关于 ConcurrentModificationException 的详细解释,参看以下内容,
摘自《JDK API1.6.0》
java.util
类 ConcurrentModificationException
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.util.ConcurrentModificationException
所有已实现的接口:
Serializable
public class ConcurrentModificationException
extends RuntimeException
当
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
检测到对象的并发修改,但不允许这种修改时,抛出此
异常。
例如,某个线程在 Collection 上进行迭代时,通常不允许另
一个线性修改该 Collection。通常在这些情况下,迭代的结果是不
确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的
所有通用 collection 实现)可能选择抛出此异常。执行该操作的
迭代器称为快速失败 迭代器,因为迭代器很快就完全失败,而不会
冒着在将来某个时间任意发生不确定行为的风险。
注意,此异常不会始终指出对象已经由不同 线程并发修改。如
果单线程发出违反对象协定的方法调用序列,则该对象可能抛出此
异常。例如,如果线程使用快速失败迭代器在 collection 上迭代
时直接修改该 collection,则迭代器将抛出此异常。
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
3
注意,迭代器的快速失败行为无法得到保证,因为一般来说,
不可能对是否出现不同步并发修改做出任何硬性保证。快速失败操
作会尽最大努力抛出 ConcurrentModificationException。因此,
为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的
做法,正确做法是:ConcurrentModificationException 应该仅用
于检测 bug。
下面来谈如何解决!
解决方案之一:用另一个集合(比如 List)记录要删除的元素信
息,待遍历完成之后,进行删除操作;
这样,结果是正确的!
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
4
解决方案之二:使用迭代器 Iterator,进行元素的删除操作;
这样写,我想应该更合理吧!
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
5
二者结果完全一样的!
解决方案之三:使用 CopyOnWriteArrayList 进行元素的删除操作,
它是 ArrayList 的一个线程安全的变体,其中所有可变操作(add、set
等等)都是通过对底层数组进行一次新的复制来实现的;
前提:CopyOnWriteArrayList 替换掉 ArrayList;
结果正确,方案可行!
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
6
关于 CopyOnWriteArrayList 的详细解释,参看以下内容,摘自《JDK
API1.6.0》
java.util.concurrent
类 CopyOnWriteArrayList
java.lang.Object
java.util.concurrent.CopyOnWriteArrayList
类型参数:
E - 此 collection 中所保存元素的类型
所有已实现的接口:
Serializable, Cloneable, Iterable, Collection, List, RandomAccess
public class CopyOnWriteArrayList
extends Object
implements List, RandomAccess, Cloneable, Serializable
ArrayList 的一个线程安全的变体,其中所有可变操作(add、
set 等等)都是通过对底层数组进行一次新的复制来实现的。
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
7
这一般需要很大的开销,但是当遍历操作的数量大大超过可变操
作的数量时,这种方法可能比其他替代方法更 有效。在不能或不想
进行同步遍历,但又需要从并发线程中排除冲突时,它也很有用。
“快照”风格的迭代器方法在创建迭代器时使用了对数组状态的引
用。此数组在迭代器的生存期内不会更改,因此不可能发生冲突,
并且迭代器保证不会抛出 ConcurrentModificationException。创
建迭代器以后,迭代器就不会反映列表的添加、移除或者更改。在
迭代器上进行的元素更改操作(remove、set 和 add)不受支持。
这些方法将抛出 UnsupportedOperationException。 允许使用所有
元素,包括 null。
内存一致性效果:当存在其他并发 collection 时,将对象放入
CopyOnWriteArrayList 之前的线程中的操作 happen-before 随后
通过另一线程从 CopyOnWriteArrayList 中访问或移除该元素的操
作。
解决方案之四:如果确定每次遍历只删除一个元素,使用 break
语句跳转,从而实现元素的删除操作;
ConcurrentModificationException 快速失败迭代器异常案例及四种解决方案
by codebrother v1.0
8
由于这种方法有特殊的条件环境,属于“自作聪明”的方法,
不适应本案例(结果是不正确的),但不失为一种方法。
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
:以上四种方法,各有各的好处,同时也有不足,这就看
你对程序的性能要求了,我的此程序用了多线程,因此首选第二
种。PS:其实由于现在的硬件配置,再加上编译器对代码的优化,小
程序几乎是比较不出来差别的,所以解决问题、积累经验是王道。
以上难免有不足之处,还望大家批评指正。
共同学习,共同成长!