1、解决:

fail-fast机制,是一种错误检测机制。它只能被用来检测错误,因为JDK并不保证fail-fast机制一定会发生。若在多线程环境下使用fail-fast机制的集合,建议使用“java.util.concurrent包下的类”去取代“java.util包下的类”。
所以,本例中只需要将ArrayList替换成java.util.concurrent包下对应的类即可。

需要将代码:private static List<String> list = new ArrayList<String>();

替换为:private static List<String> list = new CopyOnWriteArrayList<String>();

2、原因:

产生fail-fast事件,是通过抛出ConcurrentModificationException异常来触发的。
那么,ArrayList是如何抛出ConcurrentModificationException异常的呢?

接下来,我们再系统的梳理一下fail-fast是怎么产生的。步骤如下:
(01) 新建了一个ArrayList,名称为arrayList。
(02) 向arrayList中添加内容。
(03) 新建一个“线程a”,并在“线程a”中通过Iterator反复的读取arrayList的值。
(04) 新建一个“线程b”,在“线程b”中删除arrayList中的一个“节点A”。
(05) 这时,就会产生有趣的事件了。
       在某一时刻,“线程a”创建了arrayList的Iterator。此时“节点A”仍然存在于arrayList中,创建arrayList时,expectedModCount = modCount(假设它们此时的值为N)。
       在“线程a”在遍历arrayList过程中的某一时刻,“线程b”执行了,并且“线程b”删除了arrayList中的“节点A”。“线程b”执行remove()进行删除操作时,在remove()中执行了“modCount++”,此时modCount变成了N+1!
“线程a”接着遍历,当它执行到next()函数时,调用checkForComodification()比较“expectedModCount”和“modCount”的大小;而“expectedModCount=N”,“modCount=N+1”,这样,便抛出ConcurrentModificationException异常,产生fail-fast事件。

至此,我们就完全了解了fail-fast是如何产生的!
即,当多个线程对同一个集合进行操作的时候,某线程访问集合的过程中,该集合的内容被其他线程所改变(即其它线程通过add、remove、clear等方法,改变了modCount的值);这时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。

3、调用CopyOnWriteArrayList的原因:

从中,我们可以看出:

(01) 和ArrayList继承于AbstractList不同,CopyOnWriteArrayList没有继承于AbstractList,它仅仅只是实现了List接口。
(02) ArrayList的iterator()函数返回的Iterator是在AbstractList中实现的;而CopyOnWriteArrayList是自己实现Iterator。
(03) ArrayList的Iterator实现类中调用next()时,会“调用checkForComodification()比较‘expectedModCount’和‘modCount’的大小”;但是,CopyOnWriteArrayList的Iterator实现类中,没有所谓的checkForComodification(),更不会抛出ConcurrentModificationException异常!

不理解的请看原文:https://www.cnblogs.com/shamo89/p/6685216.html

面试笔记--Fast-Fail(快速失败)机制的更多相关文章

  1. 快速失败机制--fail-fast

    fail-fast 机制是Java集合(Collection)中的一种错误机制.当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast(快速失败)事件.例如:当某一个线程A通过iter ...

  2. 关于java中ArrayList的快速失败机制的漏洞——使用迭代器循环时删除倒数第二个元素不会报错

    一.问题描述 话不多说,先上代码: public static void main(String[] args) throws InterruptedException { List<Strin ...

  3. windows系统的快速失败机制---fastfail

    windows系统的快速失败机制---fastfail,是一种用于“快速失败”请求的机制 — 一种潜在破坏进程请求立即终止进程的方法. 无法使用常规异常处理设施处理可能已破坏程序状态和堆栈至无法恢复的 ...

  4. java中的fail-fast(快速失败)机制

    java中的fail-fast(快速失败)机制 简介 fail-fast机制,即快速失败机制,是java集合中的一种错误检测机制.当在迭代集合的过程中对该集合的结构改变是,就有可能会发生fail-fa ...

  5. 【原创】快速失败机制&失败安全机制

    这是why技术的第29篇原创文章 之前在写<这道Java基础题真的有坑!我求求你,认真思考后再回答.>这篇文章时,我在8.1小节提到了快速失败和失败安全机制. 但是我发现当我搜索" ...

  6. Java集合框架中的快速失败(fail—fast)机制

      fail-fast机制,即快速失败机制,是java集合框架中的一种错误检测机制.多线程下用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除),则会抛出Concurre ...

  7. 快速失败/报错机制 - fail-fast

    一.快速报错机制(fail-fast) 这是<Java编程思想>中关于快速报错机制的描述 Java容器有一种保护机制,能够防止多个进程同时修改同一个容器的内容.如果在你迭代遍历容器的过程中 ...

  8. (简单易懂)Java的快速失败(fail-fast)与安全失败,源码分析+详细讲解

    之前在程序中遇到快速失败的问题,在网上找解释时发现网上的问题总结都比较片面,故打算自己总结一个,也可以供以后参考. --宇的季节 首先什么是快速失败? 快速失败是为了提示程序员在多线程的情况下不要用线 ...

  9. 快速失败(fail—fast)和 安全失败(fail—safe)

    快速失败(fail-fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加.删除),则会抛出Concurrent Modification Exception. 原理 ...

随机推荐

  1. Linux网络编程--socket

    1.socket的核心思想是,作为服务器间的进程间通信的最底层的实现,常用的大部分网络协议都是基于socket实现. 2.socket 是如何与最终的低层收发包建立联系的? 3.socket 是如何与 ...

  2. iOS----------The app's Info.plist must contain an NSPhotoLibraryUsageDescription key

    This app has crashed because it attempted to access privacy-sensitive data without a usage descripti ...

  3. 性能优化4--Bitmap内存优化

    1.Bitmap在Android虚拟机中的内存分配 在Android3.0之前,Bitmap的内存分配分为两部分,一部分是分配在Dalvik的VM堆中.而像素数据的内存是分配在Native堆中,而到了 ...

  4. leetcode-28.实现strStr()

    leetcode-28.实现strStr() 题意 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字 ...

  5. tkinter——GUI设计实操

    1.创建root: from tkinter import * root = Tk() root.title('GUI设计') # root.attributes("-alpha" ...

  6. ELK的sentinl告警配置详解

    背景 sentinl的监控&告警是通过watch实现的. 一.Watch Execution 执行开始的时候, watcher为watch创建watch执行上下文. 执行上下文提供脚本和模板, ...

  7. Linux下图形数据库Neo4j单机安装

    Neo4j数据库简介 Neo4j 是一个NoSQL的图形数据库(Graph Database).Neo4j使用图(graph)相关的概念来描述数据模型,把数据保存为图中的节点以及节点之间的关系.很多应 ...

  8. SQL Server 锁实验(UPDATE加锁探究)

    update语句: 本例中由于看到的是update执行完的锁情况,因此无法看到IU锁,但其实针对要修改的数据页和索引页会先加IU锁,记录和键先加U锁,然后再转化为IX和X锁. 如果想要看到IU锁和U锁 ...

  9. emacs 绑定快捷键 c/c++

    ;;跳转到函数定义的地方 (global-set-key (kbd "C-<f2>") 'ggtags-find-definition) ; Control+F2 ;; ...

  10. python创建列表和向列表添加元素方法

    今天的学习内容是python中的列表的相关内容. 一.创建列表 1.创建一个普通列表 >>> tabulation1 = ['大圣','天蓬','卷帘'] >>> ...