这里是目录标题

  • 1. Fail Fast
    • a. 概念
    • b. 原理
    • c. 关注点
    • d. 注意
  • 2. Fail Safe
    • a. 概念
    • b. 原理
  • 3. Fail Fast 和 Fail Safe的区别

1. Fail Fast

a. 概念

在Java中可以使用Iterator来遍历集合对象。当一个线程使用iterator遍历集合元素时,如果集合的数据被修改了(增、删、改),支持Fail Fast的iterator会立刻抛出ConcurrentModificationExcepton异常。

  • 支持Fail Fast迭代器的集合对象有ArrayList, HashMap, Vector

b. 原理

fail-fast iterators使用了一个叫modCount的内部标识来标志集合数据是否被修改,每当集合的数据有修改,modCount就会被更新。每当iterator调用next()获取下一个集合元素时,都会检查modCount,如果发现在iterator被创建后,modCount值被修改了,就会抛出ConcurrentModificationExcepton异常。

// Java code to illustrate
// Fail Fast Iterator in Java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; public class FailFastExample { public static void main(String[] args) { Map<String, String> cityCode = new HashMap<String, String>(); cityCode.put("Delhi", "India"); cityCode.put("Moscow", "Russia"); cityCode.put("New York", "USA"); Iterator iterator = cityCode.keySet().iterator(); while (iterator.hasNext()) { System.out.println(cityCode.get(iterator.next())); // adding an element to Map // exception will be thrown on next call // of next() method. cityCode.put("Istanbul", "Turkey"); } }
}

OutPut

India
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.HashMap H a s h I t e r a t o r . n e x t N o d e ( H a s h M a p . j a v a : 1442 ) a t j a v a . u t i l . H a s h M a p HashIterator.nextNode(HashMap.java:1442) at java.util.HashMap HashIterator.nextNode(HashMap.java:1442)atjava.util.HashMapKeyIterator.next(HashMap.java:1466)
at FailFastExample.main(FailFastExample.java:18)

c. 关注点

  1. 当使用iterator遍历集合时,如果集合元素被修改,就会抛出ConcurrentModificationException
  2. 迭代器使用原始集合遍历集合元素
  3. 这些迭代器不需要额外的内存空间
  4. ArrayList, HashMap, Vector返回的迭代器支持Fail Fast

d. 注意

  1. 迭代器的快速失败行为不能得到保证,因为一般来说,在存在非同步并发修改时不可能做出任何硬性保证(比如类似ABA的问题可能会发生)。快速失败迭代器尽最大努力抛出ConcurrentModificationException。因此,如果要编写一个依赖于这个异常来保证其正确性的程序,那将是错误的:迭代器的快速失败行为应该仅用于检测错误。
  2. 如果通过Iterator remove()方法删除元素,则不会抛出异常。但是,在通过特定集合的remove()方法进行删除时,将抛出ConcurrentModificationException。下面是示例:
// Java code to demonstrate remove
// case in Fail-fast iterators import java.util.ArrayList;
import java.util.Iterator; public class FailFastExample { public static void main(String[] args) { ArrayList<Integer> al = new ArrayList<>(); al.add(1); al.add(2); al.add(3); al.add(4); al.add(5); Iterator<Integer> itr = al.iterator(); while (itr.hasNext()) { if (itr.next() == 2) { // will not throw Exception itr.remove(); } } System.out.println(al); itr = al.iterator(); while (itr.hasNext()) { if (itr.next() == 3) { // will throw Exception on // next call of next() method al.remove(3); } } }
}

OutPut

[1, 3, 4, 5]
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList I t r . c h e c k F o r C o m o d i f i c a t i o n ( A r r a y L i s t . j a v a : 901 ) a t j a v a . u t i l . A r r a y L i s t Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList Itr.checkForComodification(ArrayList.java:901)atjava.util.ArrayListItr.next(ArrayList.java:851)
at FailFastExample.main(FailFastExample.java:28)

2. Fail Safe

a. 概念

首先,在许多地方都没有给出故障安全这个术语,因为Java SE规范没有使用这个术语。我使用这个术语来演示快速失败迭代器和非失败快速迭代器之间的区别。这些迭代器复制内部集合(对象数组)并遍历复制的集合。对迭代器所做的任何结构修改都会影响复制的集合,而不是原始的集合。因此,原始集合在结构上保持不变。

当一个线程使用iterator遍历集合元素时,如果集合的数据被修改了(增、删、改),支持Fail Safe的iterator不会异常。这是因为迭代器是在集合对象的拷贝上操作,而不是直接操作原集合对象。

  • java.util.concurrent下的包如CopyOnWriteArrayList, ConcurrentHashMap都是支持Fail Safe的。

b. 原理

  1. 使用原始集合的副本遍历集合的元素,比如:CopyOnWriteArrayList
// Java code to illustrate
// Fail Safe Iterator in Java
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator; class FailSafe { public static void main(String args[]) { CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<Integer>(new Integer[] { 1, 3, 5, 8 }); Iterator itr = list.iterator(); while (itr.hasNext()) { Integer no = (Integer)itr.next(); System.out.println(no); if (no == 8) // This will not print, // hence it has created separate copy list.add(14); } }
}

OutPut

1
3
5
8

  1. 另外,那些不使用fail-fast概念的集合可能不需要在内存中创建克隆/快照来避免ConcurrentModificationException。例如,在ConcurrentHashMap的情况下,它不会对单独的副本进行操作,尽管它不是Fail Fast。相反,它的语义被官方规范描述为弱一致性(Java中的内存一致性属性)。

ConcurrentHashMap返回的迭代器是弱一致的。这意味着该迭代器可以容忍并发修改,在构造迭代器时遍历元素,并且可以(但不保证)在构造迭代器后反映对集合的修改。

// Java program to illustrate
// Fail-Safe Iterator which
// does not create separate copy
import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator; public class FailSafeItr { public static void main(String[] args) { // Creating a ConcurrentHashMap ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>(); map.put("ONE", 1); map.put("TWO", 2); map.put("THREE", 3); map.put("FOUR", 4); // Getting an Iterator from map Iterator it = map.keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); System.out.println(key + " : " + map.get(key)); // This will reflect in iterator. // Hence, it has not created separate copy map.put("SEVEN", 7); } }
}

OutPut

ONE : 1
FOUR : 4
TWO : 2
THREE : 3
SEVEN : 7

3. Fail Fast 和 Fail Safe的区别

主要的区别是,与Fail Fast相反,Fail Safe Iterator不会抛出任何异常。这是因为它们在集合的克隆上工作,而不是在原始集合上工作,这就是它们被称为故障安全迭代器的原因。


参考文章:https://www.geeksforgeeks.org/fail-fast-fail-safe-iterators-java/

什么是Fail Fast和Fail Safe?相关推荐

  1. Fail Fast与Fail Safe的区别

    Fail Fast Fail Fast Iterator在遍历集合时,若该集合发生了结构性的改变,则将抛出 ConcurrentModification 异常.例如: Map<String, S ...

  2. 聊聊hikari与tomcat jdbc pool的fail fast

    序 本文主要研究在中途数据库挂的情况下,hikari与tomcat jdbc pool的fail fast情况. 实验代码 @Testpublic void testDatabaseDownAndUp ...

  3. Java - Java集合中的快速失败Fail Fast 机制

    文章目录 什么是 fail-fast 源码解读 Itr 为什么对集合的结构进行修改会发生并发修改异常-源码分析 修改方法之 remove 修改方法之 add 案例分享 [案例一] [案例二] [案例三 ...

  4. 【转载】ArrayList 中数据删除 fail fast

    2019独角兽企业重金招聘Python工程师标准>>> 本文转载自http://shift-alt-ctrl.iteye.com/blog/1839147 在循环arrayLlist ...

  5. 【springcloud问题】Could not locate PropertySource and the fail fast property is set, failing

    问题描述:使用springcloud的本地配置中心时出现:Could not locate PropertySource and the fail fast property is set, fail ...

  6. 【android录屏填坑】录屏报错start fail,stop fail

    先写个标题,有时间了填充内容. 时隔N天,终于忙完了.内容填充中-- 前言 为什么要写这么一篇文章.因为我最近做录屏实在是被坑哭了.不是遇到start fail报错,就是遇到stop fail报错,这 ...

  7. 网络安全架构部署:Fail Closed,Fail Open,Fail safe,Fail over是什么意思?

    目录 1.Fail Closed(故障关闭) 故障关闭的用例和好处 部署故障关闭注意事项 2.Fail Open(故障打开) 故障打开的用例及好处 部署故障打开注意事项 3.Fail Safe(故障保 ...

  8. Fail - Fast机制

    平常在使用集合的时候肯定会遇到过遍历删除集合中的某些元素,哪么在进行操作的时候大家有 没有遇到过什么问题呢?最近在使用集合进行遍历删除元素的时候,我就碰到了这个异常:java.util.Concurr ...

  9. Java集合篇:fail-fast机制 与 fail-safe

    在JDK的Collection中我们时常会看到类似于这样的话: 例如,ArrayList: 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证.快速失 ...

最新文章

  1. Go基础系列:双层channel用法示例
  2. antd源码解读(4)- ButtonGroup
  3. Java13的API_JAVA基础--JAVA API常见对象(其他API)13
  4. 小学生计算机按键分布图,人教版(新版)小学信息三下第2课《常用按键掌握牢》课件.ppt...
  5. 2012.02.13(rtsp)
  6. ARM计划将四核心CPU引入磁盘驱动器
  7. Oracle 索引的分类
  8. 华为IPD 研发模式
  9. 广州传智播客.net一期训练营学习感悟(一)求学之路
  10. 机器学习:线性模型-多重共线性问题的解决-岭回归
  11. 一名年薪百万阿里P8架构师写给Java程序员一些建议(架构师必备)
  12. 人工智能就业前景如何?
  13. 在Ubuntu20.04运行VINS-Fusion
  14. 运维自动化之----ansible中play的高级用法模板(7)
  15. 冬令营2015 酱油记
  16. 解决Mac绿联 拓展坞 网线接口无法使用问题
  17. 以大数据重塑K12在线教育
  18. 从源码分析 MySQL Group Replication 的流控机制
  19. 织梦模板修改方法(转)
  20. Java包名如何命名

热门文章

  1. 计算机上标和下标的快捷键,三步法教你迅速在Word中设置上标和下标,上标与下标的快捷键是什么?...
  2. 北京计算机研究生学校排行榜,计算机考研学校的前几个排名
  3. van-action-sheet 性别选择
  4. C#中的延时函数sleep怎么使用
  5. 2020年来了,关于人工智能你必须了解的这些事……
  6. U.2 NVMe硬盘太香了,搭配这款硬盘盒,视频剪辑速度又提升!
  7. 硬件电路设计之——DC-DC上电时电压输出尖峰电压
  8. 微信小程序动态实时获取当前时间
  9. python有趣小程序春节祝福-python3:春节自动回复祝福(微信)
  10. 斗鱼直播弹幕python_python利用danmu实时获取斗鱼等直播网站字幕