内容简介:在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出ConcurrentModificationException。采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问,而是先复制原有集合内容,在拷贝的集合上进行遍历。快速失败和安全失败是对迭代器而言的。快速失败:挡在迭代一个集合的时候,如果有另外一个线程在修改这个集合,就会抛出ConcurrentModificationException,java.utl下都是快速失败。安全失败:在迭代时候会在集合
在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出ConcurrentModificationException。
-
原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个modCount变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hasNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedModCount值,是的话就返回遍历;否则抛出异常,终止遍历。
-
注意:这里异常的抛出条件是检测到modCount != expectedModCount这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedModCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的变成,这个异常只建议用于检测并发修改的bug。
- 场景:java.utl包下的集合类都是快速失败的,不能再多线程下发生并发修改(迭代过程中被修改)。
安全失败(fail-safe)
采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问,而是先复制原有集合内容,在拷贝的集合上进行遍历。
- 原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发ConcurrentModificationException。
-
缺点:
- 基于拷贝内容的优点是避免了ConcurrentModificationException,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
- 需要复制集合,产生大量的无效对象,开销大。
- 场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
快速失败和安全失败是对迭代器而言的。快速失败:挡在迭代一个集合的时候,如果有另外一个线程在修改这个集合,就会抛出ConcurrentModificationException,java.utl下都是快速失败。安全失败:在迭代时候会在集合二层做一个拷贝,所以在修改集合上层元素不会影响下层。在java.util.concurrent下都是安全的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java编程思想 (第4版)
[美] Bruce Eckel / 陈昊鹏 / 机械工业出版社 / 2007-6 / 108.00元
本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形。从Java的基础语法到最高级特性(深入的面向对象概念、多线程、自动项目构建、单元测试和调试等),本书都能逐步指导你轻松掌握。 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作。本书的作者拥有多年教学经验,对C、C++以及Java语言都有独到......一起来看看 《Java编程思想 (第4版)》 这本书的介绍吧!