原文地址:http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fail-safe-iterator-difference-with-example-in-Java.html
在我们详细讨论这两种机制的区别之前,首先得先了解并发修改。
1.什么是并发修改?
当一个或多个线程正在遍历一个集合Collection,此时另一个线程修改了这个集合的内容(添加,删除或者修改)。这就是并发修改。
2.什么是 fail-fast 机制?
fail-fast机制在遍历一个集合时,当集合结构被修改,会抛出Concurrent Modification Exception。
fail-fast会在以下两种情况下抛出ConcurrentModificationException
(1)单线程环境
集合被创建后,在使用Iterator遍历它的过程中修改了结构。
注意Iterator的 remove()方法会让expectModcount和modcount 相等,所以是不会抛出这个异常。
(2)多线程环境
当一个线程在遍历这个集合,而另一个线程对这个集合的结构进行了修改。
注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。
3. fail-fast机制是如何检测的?
迭代器在遍历过程中是直接访问内部数据的,因此内部的数据在遍历的过程中无法被修改。为了保证不被修改,迭代器内部维护了一个标记 “mode” ,当集合结构改变(添加删除或者修改),标记"mode"会被修改,而迭代器每次的hasNext()和next()方法都会检查该"mode"是否被改变,当检测到被修改时,抛出Concurrent Modification Exception。
下面看看ArrayList迭代器部分的源码:
- private class Itr implements Iterator<E> {
- int cursor;
- int lastRet = -1;
- int expectedModCount = ArrayList.this.modCount;
- public boolean hasNext() {
- return (this.cursor != ArrayList.this.size);
- }
- public E next() {
- checkForComodification();
- /** 省略此处代码 */
- }
- public void remove() {
- if (this.lastRet < 0)
- throw new IllegalStateException();
- checkForComodification();
- try {
- ArrayList.this.remove(lastRet);
- cursor = lastRet;
- lastRet = -1;
- expectedModCount = modCount;
- } catch (IndexOutOfBoundsException ex) {
- throw new ConcurrentModificationException();
- }
- }
- final void checkForComodification() {
- if (ArrayList.this.modCount == this.expectedModCount)
- return;
- throw new ConcurrentModificationException();
- }
- }
可以看到它的标记“mode”为 expectedModeCount
4. fail-safe机制
fail-safe任何对集合结构的修改都会在一个复制的集合上进行修改,因此不会抛出ConcurrentModificationException
fail-safe机制有两个问题
(1)需要复制集合,产生大量的无效对象,开销大
(2)无法保证读取的数据是目前原始数据结构中的数据。
5.fail-fast 和 fail-safe的例子
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- public class FailFastExample
- {
- public static void main(String[] args)
- {
- Map<String,String> premiumPhone = new HashMap<String,String>();
- premiumPhone.put("Apple", "iPhone");
- premiumPhone.put("HTC", "HTC one");
- premiumPhone.put("Samsung","S5");
- Iterator iterator = premiumPhone.keySet().iterator();
- while (iterator.hasNext())
- {
- System.out.println(premiumPhone.get(iterator.next()));
- premiumPhone.put("Sony", "Xperia Z");
- }
- }
- }
输出
iPhone Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(Unknown Source) at java.util.HashMap$KeyIterator.next(Unknown Source) at FailFastExample.main(FailFastExample.java:20)
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.Iterator;
- public class FailSafeExample
- {
- public static void main(String[] args)
- {
- ConcurrentHashMap<String,String> premiumPhone =
- new ConcurrentHashMap<String,String>();
- premiumPhone.put("Apple", "iPhone");
- premiumPhone.put("HTC", "HTC one");
- premiumPhone.put("Samsung","S5");
- Iterator iterator = premiumPhone.keySet().iterator();
- while (iterator.hasNext())
- {
- System.out.println(premiumPhone.get(iterator.next()));
- premiumPhone.put("Sony", "Xperia Z");
- }
- }
- }
输出
S5 HTC one iPhone
6. fail-fast和 fail-safe 的区别
相关推荐
在多线程并发操作中,Fail-safe机制和Fail-fast机制是两种常见的失败处理机制,它们的作用和实现原理有所不同。 Fail-fast机制是一种快速失败机制,在集合遍历过程中,一旦发现容器中的数据被修改了,会立刻抛出...
理解Fail-fast和Fail-safe迭代器的区别对于编写健壮的多线程程序至关重要。Fail-fast迭代器提供了快速的错误检测,防止意外的数据一致性问题,但不适用于并发修改的场景。而Fail-safe迭代器则允许在遍历过程中安全地...
掌握 Iterator 的 fail-fast 、fail-safe 机制 ArrayList() 会使用长度为零的数组 ArrayList(int initialCapacity) 会使用指定容量的数组 public ArrayList(Collection<? extends E> c) 会使用 c 的大小作为数组...
* fail-fast与fail-safe:Java集合在遍历时可能会抛出ConcurrentModificationException异常,这是因为集合在遍历时可能会被修改。fail-fast机制将抛出异常,而fail-safe机制将忽略修改。 * transient关键字:在...
在遍历List集合时,存在fail-fast和fail-safe两种迭代机制。fail-fast迭代器在检测到集合结构被修改的情况下会快速抛出ConcurrentModificationException异常;fail-safe迭代器则不会抛出这种异常,因为它工作在集合...
在Java集合框架中,有两种迭代机制:“快速失败”(fail-fast)和“安全失败”(fail-safe)。快速失败机制是Java集合的默认行为,当集合在迭代过程中被修改(非迭代器自身进行的修改),会抛出`...
【Java基础】集合框架-面试题。包含: 1. ArrayList 和 Vector 的区别;...3. 快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别; 4. HashMap 的数据结构、工作原理 等Java集合部分经常遇到的面试题总结
fail-fast 和 fail-safe 迭代器是 Java Collections 框架中的两种迭代器模式。fail-fast 迭代器在集合修改时,会抛出 ConcurrentModificationException 异常。fail-safe 迭代器在集合修改时,会返回当前集合的快照。...
5. **容错机制**:Dubbo提供了多种容错策略,如Fail-fast(快速失败)、Fail-over(重试其他服务器)、Fail-safe(失败安全,忽略异常)、Forking(并行调用,只返回成功结果)等,以应对服务调用过程中可能出现的...
14. **fail-fast与fail-safe有什么区别?** fail-fast会在检测到并发修改时立即抛出异常,而fail-safe则使用复制集合的方式,允许并发修改,但可能返回旧的或不完整的结果。 15. **在迭代一个集合的时候,如何避免...
7. **fail-fast和fail-safe**:fail-fast迭代器(如ArrayList和HashSet的迭代器)在检测到集合结构被修改时会抛出ConcurrentModificationException。而fail-safe迭代器(如CopyOnWriteArrayList的迭代器)可以在多...
- **Fail-safe**:某些集合如`ConcurrentHashMap`和`CopyOnWriteArrayList`提供了一种线程安全的遍历机制,即使遍历过程中集合被修改也不会抛出异常。 - 实现机制:通过创建集合的副本进行遍历,这样就不会受到集合...
7. **容错机制**:Dubbo提供了多种容错策略,如Fail-fast(快速失败)、Fail-over(重试其他服务器)、Fail-safe(失败安全,忽略异常)、Fallback(降级处理)等,以应对服务不可用的情况。 8. **集群模式**:...
8. **Fail-fast与Fail-safe机制**:Fail-fast是指当检测到错误时立即抛出异常停止程序;Fail-safe则尝试处理错误,使程序能够继续运行。 9. **GET与POST请求的区别**:GET用于获取资源,数据在URL中可见,安全性和...
针对服务调用可能遇到的问题,Dubbo提供了多种容错策略,如Fail-fast(快速失败)、Fail-over(重试)、Fail-safe(安全失败)等,确保服务的高可用性。 8. **监控与日志**: Dubbo集成了监控中心,可以收集服务...
6. **迭代器的fail-fast与fail-safe**:fail-fast是指当集合结构发生变化时,迭代器会立即抛出`ConcurrentModificationException`。而fail-safe的迭代器(如`Collections.synchronizedList`返回的迭代器)则不会立即...
Java版水果管理系统源码 ...fail-fast 与 fail-safe 机制有什么区别 IOC的优点是什么 IO 和 NIO的区别,NIO优点 Java 8 / Java 7 为我们提供了什么新功能 什么是竞态条件? 举个例子说明。 MVC的各个部分
* HashTable的迭代器是fail-fast的,而HashMap的迭代器是fail-safe的 在Java中,Collection接口的子接口包括Set和List,分别代表无序集合和有序集合。Map接口用于保存具有key-value映射关系的数据,常见的Map实现...
快速失败(Fail-Fast)迭代器机制是指在用迭代器遍历集合的过程中,如果检测到集合在迭代过程中被修改了,就会迅速抛出ConcurrentModificationException异常。快速失败机制的迭代器是为单线程设计的,因为它们不能...
Dubbo提供的容错策略,如Fail-fast、Fail-over、Fail-safe等,可以应对网络异常或服务故障,保证系统的稳定性。同时,通过内置的监控中心,开发者可以实时查看服务的运行状态,进行性能优化。 在文件名"pay-master...