【面试:基础篇06.2:FailFast与FailSafe源码分析】

简介: 【面试:基础篇06.2:FailFast与FailSafe源码分析】

【面试:基础篇06.2:FailFast与FailSafe源码分析】

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属于读写分离 也是边读边拷贝

目录
相关文章
|
存储 缓存 前端开发
LiveData 面试题库、解答、源码分析
LiveData 面试题库、解答、源码分析
129 1
|
缓存 前端开发 Java
LiveData 面试题库、解答、源码分析(下)
LiveData 面试题库、解答、源码分析
169 0
|
自然语言处理 安全 算法
FAQ 问答系统(新冠病毒/寝室)《《让电脑理解我说的话》》------更详细的了解和掌握自然语言知识(不再害怕面试~~~)=-------= 文章中含有源码分析
FAQ 问答系统(新冠病毒/寝室)《《让电脑理解我说的话》》------更详细的了解和掌握自然语言知识(不再害怕面试~~~)=-------= 文章中含有源码分析
135 1
FAQ 问答系统(新冠病毒/寝室)《《让电脑理解我说的话》》------更详细的了解和掌握自然语言知识(不再害怕面试~~~)=-------= 文章中含有源码分析
|
存储 安全 算法
Java面试准备-基础篇
Java面试准备-基础篇
175 0
Java面试准备-基础篇
|
消息中间件 缓存 算法
堪称神级的阿里巴巴“高并发”教程《基础+实战+源码+面试+架构》
前言 作为一个普普通通的程序员,如何才能提升自己的能力,在职场上拥有一技之长,这也成为普通的你我,迫切的需求。 拥有什么样的能力才能不被淘汰?答案是:高并发,它几乎成为了每个程序员都想要拥有的经验。 原因很简单:流量是大的电商公司必要的需求,比如,淘宝的双十一会产生大量的高并发,用户上亿,一天的流量就是几十亿,高峰期的并发量上十万。所以,如何抗住高并发,是这种大公司需要面对的。 所以,你要是掌握了这项技术,工资蹭蹭地往你兜里钻。
|
机器学习/深度学习 自然语言处理 算法
机器学习:基础面试知识点
机器学习:基础面试知识点
236 0
机器学习:基础面试知识点
|
存储 缓存 NoSQL
Java基础到就业!项目加面试!之Redis面试大全!
简单来说 redis 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快,因此 redis 被广泛应用于缓存方向。
155 0
Java基础到就业!项目加面试!之Redis面试大全!
|
存储 分布式计算 Java
面试准备之并发基础
面试准备之并发基础
138 0
面试准备之并发基础
|
运维 网络协议 算法
网络基础运维面试必备的知识点(2)
网络基础运维面试必备的知识点(2)