Java集合的快速失败机制 “fail-fast”

"fail-fast"是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。

例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。

原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。

CopyOnWriteArrayList

传统的List在多线程同时读写的时候会抛出java.util.ConcurrentModificationException,

Vector是线程安全的,但是由于使用了synchronized同步锁,导致同一时间内只有一个线程能访问,效率较低。

而CopyOnWriteArrayList是使用CopyOnWrite(写时复制)技术解决了这个问题,这一般需要很大的内存开销。

/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}

java并发:CopyOnWriteArrayList简单理解的更多相关文章

  1. Java 层级的简单理解

    在J2EE项目中,开发的都是分层来做的: 1.service层:用于暴露给网络调用 2.Impl层:统一规范接口 3.bean层:实体对象,也就是表 4.DAO(Data Access Object) ...

  2. Java 集合的简单理解

    集合(容器) Java的集合类分别是Collection接口和Map接口派生而来. Collection接口 对于实现Collection接口的子类,都会实现Collection接口中抽象方法,所以他 ...

  3. java并发:简单面试问题集锦

    多线程:Simultaneous Multithreading,简称SMT. 并行.并发 并行性(parallelism)指两个或两个以上的事件在同一时刻发生,在多道程序环境下,并行性使多个程序同一时 ...

  4. Java接口的简单理解和总结

    1.抽象层次:普通类 -> 抽象类 -> 接口 普通类:就是我们常用的类: 抽象类:专门用来被子类继承的,主要是为了符合现实世界的规律 如: Animal类:(每个现实的对象都有类与它相对 ...

  5. Java并发-CopyOnWriteArrayList

    前言 今天我们一起学习下java.util.concurrent并发包里的CopyOnWriteArrayList工具类.当有多个线程可能同时遍历.修改某个公共数组时候,如果不希望因使用synchro ...

  6. java双指针的简单理解

    一.什么是双指针 双指针我所理解地是在遍历对象时,不是使用单个指针进行访问,而是使用两个相同方向或者相反方向的指针进行遍历,从而达到相应的目的. 在JAVA中并没有像C/C++指针地概念,所以这里所说 ...

  7. java 的 IO简单理解

    首先要先理解什么是 stream ? stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源. 一.不同导向的 stream 1)以字节为单位从 stream 中读取或往 st ...

  8. Java虚拟机JVM简单理解

    Java虚拟机JVM的作用: Java源文件(.java)通过编译器编译成.class文件,.class文件通过JVM中的解释器解释成特定机器上的机器代码,从而实现Java语言的跨平台. JVM的体系 ...

  9. java 线程的简单理解

    想要实现线程可以继承Thread也可以实现接口runnable,在类中重写 run()方法在主函数调用start方法就可以开辟线程. 对于java对象都有一个wait()和notify().notif ...

随机推荐

  1. zookeeper(1)初识zookeeper

    一.zookeeper的安装 1.下载zookeeper(当然在安装zookeeper之前得先装好jdk,这里就不说了),版本自己随便选一个(后面我再说版本的问题),点击这里下载. 2.然后在usr下 ...

  2. RDD编程接口

    Spark中提供了通用接口来抽象每个RDD,这些接口包括: 1.分区信息 2.依赖关系 3.函数,基于父RDD计算方法 4.划分策略和数据位置的元数据

  3. log4js_Node.js中的日志管理模块使用

    { "appenders": [ // 下面一行应该是用于跟express配合输出web请求url日志的 {"type": "console" ...

  4. flex学习笔记 使用函数,显示实时更新的标签

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  5. react-navigation,StackNavigator,TabNavigator 导航使用

    StackNavigator  参考这里 TabNavigator  参考这里 是一个组合,我把这2个写在一起了 代码: import React, { Component } from 'react ...

  6. mfc cef<转>

    在mfc单文档程序中加入cef: .在BOOL CtestCEFApp::InitInstance()中初始化cef HINSTANCE hInst = GetModuleHandle(NULL); ...

  7. (已解决)搭建ssm框架时给springmvc传入对象传不进去,传单个字符串可以

    问题如题: springmvc会自动解析传入的内容,只要将表单中的对象名字和pojo一一对应,否则会报错. jsp默认好像是会加上请求头. 如果要是用其他的方式去给接口传入对象.要加上请求头. Con ...

  8. gevent mysql

    使用gevent实现mysql并发时,每个greenlet应该独享一个mysql连接,否则,不同的greenlet之间会相互影响. ultramysql doesn't allow you to ma ...

  9. 尚硅谷springboot学习6-eclipse创建springboot项目的三种方法(转)

    方法一 安装STS插件 安装插件导向窗口完成后,在eclipse右下角将会出现安装插件的进度,等插件安装完成后重启eclipse生效 新建spring boot项目 项目启动 方法二 1.创建Mave ...

  10. mycat 单库分表

    上次把mycat的读写分离搞定了,这次试下单库分表,顾名思义就是在一个库里把一个表拆分为多个 需要配置的配置文件为 schema.xml 配置内容如下 <!DOCTYPE mycat:schem ...