【面试:基础篇06:FailFast与FailSafe机制】

00.前言

有任何问题还请指出,感谢。

01.介绍:

迭代器进行迭代操作时是否可以修改被迭代对象 分为了 两种机制 一种是:FailFast机制,另一个是:FailSafe。

01.FailFast

FailFast机制是迭代器进行迭代操作时不可以修改被迭代对象,否则会抛出ConcurrentModificationException 译为 并发异常,主要的应用场景就是 多线程同时操作一个被迭代对象 为了保证数据的一致性 抛出异常。

02.FailFast

FailSafe机制是迭代器进行操作时可以修改被迭代对象,不会抛出异常 但迭代过程中 被迭代对象的值不变,迭代后改变被迭代对象。

02.代码

FailFast代码

ArrayList<Integer> L=new ArrayList<>();for (int i=0;i<5;i++) {L.add(i);}Iterator<Integer> it = L.iterator();while (it.hasNext()){int val = it.next();L.add(5);// 在迭代器遍历过程中出现报错 ConcurrentModificationException 并发修改异常System.out.println(val);
}

结果

0
Exception in thread “main” java.util.ConcurrentModificationException

可以看出ArrayList()是FailFast机制抛出异常

FailSafe代码

CopyOnWriteArrayList<Integer> L = new CopyOnWriteArrayList<>();for (int i=0;i<5;i++) {L.add(i);}Iterator<Integer> it = L.iterator();while (it.hasNext()) {int val = it.next();L.add(9);System.out.printf("%d ",val);}System.out.println();System.out.println(L);
}

结果

0 1 2 3 4
[0, 1, 2, 3, 4, 9, 9, 9, 9, 9]

可以看出CopyOnWriteArrayList()是FailSafe机制,在迭代器过程中遍历结果不变,遍历结束后输出list 发现插入成功

03.FailFast源码分析

ArrayList<Integer> L=new ArrayList<>();
for (int i=0;i<5;i++) {L.add(i);
}
Iterator<Integer> it = L.iterator();
while (it.hasNext()){int val = it.next();L.add(5);// 在迭代器遍历过程中出现报错 ConcurrentModificationException 并发修改异常System.out.println(val);
}

我们进入ArrayList()的迭代器Iterator it = L.iterator();

我们应该关注两个变量 expectedModCount与modCount

modCount记录ArrayList集合修改了多少次,这个例子中因为add添加了5次 所以modCount为5

expectedModCount是迭代器成员变量,记录了刚开始ArrayList修改了多少次,初始化expectedModCount=modCount=5

接下来我们应该关注 每次执行add方法会 先执行 checkForComodification()方法

我们可以看出checkForComodification()方法是判断expectedModCount与modCount是否相等,如果不等 说明ArrayList集合被修改了 因为我们在迭代过程中又add了一个元素 所以此时modCount=6 expectedModCount=5,expectedModCount!=modCount 所以 throw new ConcurrentModificationException(); 就是我们看到的抛出 并发异常。

乐观锁的思想:即并发情况下 乐观的认为所有的操作都不会修改数据 所以不会上锁 只有遇到了并发操作的情况下 才会报错 抛出异常。

FailSafe源码分析

CopyOnWriteArrayList<Integer> L = new CopyOnWriteArrayList<>();
for (int i=0;i<5;i++) {L.add(i);
}
Iterator<Integer> it = L.iterator();
while (it.hasNext()) {int val = it.next();L.add(9);System.out.printf("%d ",val);
}
System.out.println();
System.out.println(L);

我们进入CopyOnWriteArrayList()的迭代器Iterator it = L.iterator();

我们注意到了 COWIterator查看它

我们应该关注snapshot = elements这个语句

elements当前正在遍历的数组,snapshot记录当前正在遍历的数组,也就是说在迭代器中 遍历的是snapshot记录的数组

我们再来看看CopyOnWriteArrayList里的add方法

我们应该关注getArray();, Arrays.copyOf(elements, len + 1);,newElements[len] = e;,setArray(newElements);

getArray();拿到原来旧的数组

Arrays.copyOf(elements, len + 1); 拷贝原数组 并且长度+1

newElements[len] = e;表示把新add的元素放入新数组中

setArray(newElements);说明现在newElements是CopyOnWriteArrayList的新数组,也就说明我们迭代器结束后遍历的其实是newElements而不是迭代器中记录的数组,所以这才使得,在迭代器遍历过程中 遍历的是最开始的数组,迭代器结束后遍历的是新数组

CopyOnWriteArrayList是FailSafe的典型代表,CopyOnWriteArrayList属于读写分离 也是边读边拷贝

【面试:基础篇06:FailFast与FailSafe机制】相关推荐

  1. Java面试基础篇之集合

    文章目录 你知道的集合都有哪些? 哪些集合是线程安全的? Collection 集合类和数组有什么不同? Collection和Collections有什么区别? 如何确保一个集合不能被修改? Lis ...

  2. 2021Java面试-基础篇

    文章目录 前言 一: Java概述 1.何为编程 2.JDK1.5之后的三大版本 3.JVM,JRE和JDK的关系 4.什么是跨平台?原理是什么 5.Java语言有哪些特点 6.什么是字节码?采用字节 ...

  3. 第三十九篇:Flink 面试基础篇

    你好,欢迎来到第 39 课时,本课时我们主要讲解"Flink 面试-基础篇". 到目前为止,关于 Flink 的学习我们就告一段落了,接下来我们将进入最后一个面试模块的学习.在当前 ...

  4. 「Fail-Fast与Fail-Safe机制」

    「Fail-Fast与Fail-Safe机制」 写在前面 最近在刷题的过程中又重新熟悉一遍常用的数据结构,发现对Fail-Fast与Fail-Safe机制有点模糊了,这里重新整理一下,加深一下印象.提 ...

  5. 详解迭代器的 fail-fast 与 fail-safe 机制

    目录 fail-fast 机制 重现 fail-fast 产生 fail-fast 机制的原因 fail-safe 机制 重现 fail-safe fail-safe原理 总结 fail-fast 机 ...

  6. Python面试基础篇 - 50道经典面试题(附答案及多种解答)

    大家好,我是辣条哥 高考刚结束不久,网上各种招工的,工地招搬砖的都开始活跃了,这时候我要是不出来活跃一波感觉有点不合时宜了. 于是特意整理了这一份Python面试题的基础篇,进阶的先不说我能不能整理出 ...

  7. Fail-fast 和 Fail-safe 机制

    fail-fast 和 fail-safe 的区别 从字面意思来看 fail-fast 是快速失败,fail-safe 是安全失败,这都是集合类对于并发读写时的一种应对机制. fail-fast,广泛 ...

  8. python面试笔试宝典pdf_Python面试宝典之基础篇-06

    题目26:什么是鸭子类型(duck typing)? 鸭子类型是动态类型语言判断一个对象是不是某种类型时使用的方法,也叫做鸭子判定法.简单的说,鸭子类型是指判断一只鸟是不是鸭子,我们只关心它游泳像不像 ...

  9. MySQL基础篇(06):事务管理,锁机制案例详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.锁概念简介 1.基础描述 锁机制核心功能是用来协调多个会话中多线程并发访问相同资源时,资源的占用问题.锁机制是一个非常大的模块,贯彻MyS ...

  10. android peopleactivity.java,Android面试基础篇---Activity(上)

    ** 前言: ** 一.生命周期 1.七个方法: 1.1:onCreate() 在这里创建界面,做一些数据的初始化工作 1.2:onStart() 可见不可交互 1.3:onResume() 可见可交 ...

最新文章

  1. 搭建linux下eclipse php完美搭建开发php,搭建linux上的Eclipse+PHP编程环境
  2. zbb20180827 java获取字符串中所有汉字
  3. 9 个 Java 性能调优技巧,YYDS!
  4. linux服务器无网络确认,Linux服务器故障排查实用指南
  5. .NET中使用Memcached的相关资源整理 转载之DUDU 程序员打杂的站长
  6. PTA-习题11-2 查找星期 (15 分)-enum
  7. wxpython textctrl_wxPython TextCtrl类
  8. 《中国人工智能学会通讯》——9.2 误差的本质
  9. Win2008 R2 RemoteApp深度体验之二,RemoteApp服务器配置
  10. Java设计模式------单例模式
  11. 从Spring为什么要用IoC的支点,我撬动了整个Spring的源码脉络!
  12. 技术可行性分析注意哪些内容?
  13. Eclipse中的工作空间(Workspace)
  14. 【工具】我的键盘(机械键盘)快捷键设置
  15. https://blog.csdn.net/qq_43412289
  16. Windows 11 L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
  17. 汇编jnl_汇编指令 JO、JNO、JB、JNB、JE、JNE、JBE、JA、JS、JNS、JP、JNP、JL
  18. 网页JS自动化脚本(一)安装油猴或暴力猴等脚本管理器并新建脚本
  19. sh_10_嵌套打印小星星
  20. c语言打印地址的格式错误,printf()在c中以%p格式打印的地址是哪一个?

热门文章

  1. 计算机搜索栏历史记录,如何打开搜索历史记录
  2. python中每个if条件后面都要使用冒号_每个if条件后面都要使用冒号。
  3. android 跑马灯速度,自定义TextView跑马灯效果可控制启动/停止/速度/焦点
  4. Python学习记录—— 绘制百分比堆积柱状图
  5. 2018年全国多校算法寒假训练营练习比赛(第三场)---I---题(皮克公式)
  6. 论文格式排版技巧(word版)
  7. 先天八卦与后天八卦原理及区别
  8. mac ubuntu双系统EFI分区修复,内置磁盘分区修复
  9. Unity商店插件/工具收藏篇
  10. iosem.us app install nds.html,夭寿啦!用NDS4iOS无需越狱即可在iOS玩NDS游戏