使用CopyOnWriteArrayList来解决ArrayList上的ConcurrentModificationException

转载 2012年03月22日 10:18:32
(2010-10-14 20:07:40)
标签:

arraylist

it

分类: JAVA基础

在你的应用中有一个列表(List),它被频繁的遍历,但是很少被修改。像“你的主页上的前十个分类,它被频繁的访问,但是每个小时通过Quartz的Job来调度更新”。

如果你使用ArrayList来作为该列表的数据结构并且不使用同步(synchronization),你可能会遇到ConcurrentModificationException,因为在你使用Quartz的Job修改该列表时,其他的代码可能正在遍历该列表。

有些开发人员可能使用Vector或Collections.synchronizedList(List<T>)的方式来解决该问题。但是这并没有效果!虽然在列表上add(),remove()和get()方法现在对线程是安全的,但遍历时仍然会抛出ConcurrentModificationException!在你遍历在列表时,你需要在该列表上使用同步,同时,在使用Quartz修改它时,也需要使用同步机制。这对性能和可扩展性来说是一个噩梦。同步需要在所有的地方出现,仅仅是因为每个小时都需要做更新。

幸运的是,这里有更好的解决方案。使用CopyOnWriteArrayList。

当列表上的一个结构修改发生时,一个新的拷贝(copy)就会被创建。这在经常发生修改的地方使用,将会很低效。遍历该列表将不会出现ConcurrentModificationException,因为该列表在遍历时将不会被做任何的修改。

另一种避免添加同步代码但可以避免并发修改问题的方式是在调度任务中构建一个新的列表,然后将原来指向到列表上的引用赋值给新的列表。在JVM中,赋值一个新的引用是原子操作。这种方式在使用旧的遍历方式(for (int i=0; i<list.size(); i++) { … list.get(i) …})时将无效(也会出错)。切换的列表中的大小将引发新的错误产生。更加糟糕的是因为改变是在不同的线程中发生的,所以还会有很多潜在的问题。使用volatile关键字可能会有所帮助,但是对列表大小的改变依然会有问题。

内存一致性和刚发生后保证了CopyOnWriteArrayList的可用性。同时,代码变得更简单,因为根本不需要使用volatile关键字或同步。更少的代码,更少的bug!

CopyOnWriteArrayList的另一个使用案例是观察者设计模式。如果事件监听器由多个不同的线程添加和移除,那么使用CopyOnWriteArrayList将会使得正确性和简单性得以保证

多线程之操作CopyOnWriteArrayList解决Iterator迭代器产生java.util.ConcurrentModificationException

当我们运行如下代码时: package andy.thread.test; import java.util.ArrayList; import java.util.Collection; imp...
  • fengshizty
  • fengshizty
  • 2014年11月09日 21:27
  • 2418

ArrayList引起的ConcurrentModificationException 异常原因及解决方法

ArrayList引起的ConcurrentModificationException 异常原因及解决方法
  • lhl6688
  • lhl6688
  • 2015年02月27日 15:25
  • 852

异步读写ArrayList换用CopyOnWriteArrayList、synchronizedList、java.util.ConcurrentModificationException 异常解决

CopyOnWriteArrayList与Collections.synchronizedList的性能对比 列表实现有ArrayList、Vector、CopyOnWriteArray...
  • hhh594521
  • hhh594521
  • 2017年06月01日 11:15
  • 367

使用CopyOnWriteArrayList来解决ArrayList上的ConcurrentModificationException

http://www.xdocs.org/?p=415   使用CopyOnWriteArrayList来解决ArrayList上的ConcurrentModificationEx...
  • lluohuih
  • lluohuih
  • 2015年03月04日 16:01
  • 303

Vector与ArrayList与CopyOnWriteArrayList区别

1. Vector & ArrayList 1)  Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步...
  • sxfda
  • sxfda
  • 2015年11月25日 17:30
  • 2143

用CopyOnWriteArrayList来解决ConcurrentModificationException

除了加锁外,其实还有一种方式可以防止并发修改异常,这就是将读写分离技术(不是数据库上的)。 先回顾一下一个常识: 1、JAVA中“=”操作只是将引用和某个对象关联,假如同时有一个线程将引用...
  • gaojiaxing
  • gaojiaxing
  • 2014年06月18日 18:52
  • 486

Java基础-ArrayList中ConcurrentModificationException错误解决

ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 产生的原因: 迭代器是依赖于集合而存在的,在判断成功后,集合的中新...
  • u014657752
  • u014657752
  • 2015年08月11日 17:23
  • 966

JCIP_5_01_CopyOnWriteArrayList为什么不会产生ConcurrentModificationException?

CopyOnWriteArrayList为什么不会产生ConcurrentModificationException? 场景 多线程场景下对未正确处理并发的容器进行迭代会抛出异常(Concurre...
  • ybygjy
  • ybygjy
  • 2014年07月26日 17:57
  • 1316

深入Java集合系列之六:CopyOnWriteArrayList

CopyOnWriteArrayList简介CopyOnWriteArrayList容器是Collections.synchronizedList(List list)的替代方案,CopyOnWrit...
  • u011116672
  • u011116672
  • 2016年04月08日 16:18
  • 3403

线程安全的CopyOnWriteArrayList介绍

证明CopyOnWriteArrayList是线程安全的先写一段代码证明CopyOnWriteArrayList确实是线程安全的。ReadThread.javaimport java.util.Lis...
  • linsongbin1
  • linsongbin1
  • 2017年01月17日 16:07
  • 10030
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用CopyOnWriteArrayList来解决ArrayList上的ConcurrentModificationException
举报原因:
原因补充:

(最多只允许输入30个字)