CopyOnWriteArrayList  源码分析:

1:成员属性:

final transient ReentrantLock lock = new ReentrantLock();  //内部是通过ReentrantLock来保证线程安全的,通过一个非公平锁

private transient volatile Object[] array;  维护一个Object数组

2:构造方法  初始化一个长度为0 的Object数组  new Object[0]

public CopyOnWriteArrayList() {

setArray(new Object[0]);

}

setArray方法如下:

final void setArray(Object[] a) {

array = a;  //将初始化后的Object 数组赋值给array成员变量

}

到此初始化方法结束:主要做了以下两个初始化过程:

1:初始化创建一个长度为0 的Object数组,并且赋值给 array成员变量

2:初始化一个ReentrantLock 非公平可重入锁,之后用于保证线程安全

3:add 方法分析:以第一次添加元素元素额为例  e=”aa”

public boolean add(E e) {  // e=aa

final ReentrantLock lock = this.lock;  //使用初始化构建的ReentrantLock

lock.lock();  //加锁

try {

Object[] elements = getArray();  //获取数组成员变量array,这里为Object[0]

int len = elements.length;  // len=0

Object[] newElements = Arrays.copyOf(elements, len + 1);  //copy elements到新数组中 长度为len+1

newElements[len] = e; //将需要add的元素放置到newElements 的len索引位置

setArray(newElements);  //将新数组赋值给成员变量array

return true;

} finally {

lock.unlock();  //释放锁

}

}

Get 方法分析:

public E get(int index) {

return get(getArray(), index);  //获取成员变量array 数组的index 位置处的元素

}

总结:CopyOnWriteArrayList 每次添加一个元素的时候都会进行一下拷贝,将原始数组拷贝到长度是原始数组+1的新数组中,并且将新数组赋值给成员变量array.对性能有一定的影响;而对于读则直接读取索引的位置,效率很高。

CopyOnWriteArrayList 源码分析 基于jdk1.8的更多相关文章

  1. HashMap 源码分析 基于jdk1.8分析

    HashMap 源码分析  基于jdk1.8分析 1:数据结构: transient Node<K,V>[] table;  //这里维护了一个 Node的数组结构: 下面看看Node的数 ...

  2. HashMap源码分析-基于JDK1.8

    hashMap数据结构 类注释 HashMap的几个重要的字段 hash和tableSizeFor方法 HashMap的数据结构 由上图可知,HashMap的基本数据结构是数组和单向链表或红黑树. 以 ...

  3. ArrayList 源码分析 基于jdk1.8:

    1:数据结构: transient Object[] elementData;  //说明内部维护的数据结构是一个Object[] 数组 成员属性: private static final int ...

  4. LinkedList的源码分析(基于jdk1.8)

    1.初始化 public LinkedList() { } 并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢? 2.Node类型 存储到链表中的元素会被封装为一个Node类型的结点.并 ...

  5. ArrayList的源码分析(基于jdk1.8)

    1.初始化 transient Object[] elementData; //实际存储元素的数组 private static final Object[] DEFAULTCAPACITY_EMPT ...

  6. AtomicInteger源码分析——基于CAS的乐观锁实现

    AtomicInteger源码分析——基于CAS的乐观锁实现 1. 悲观锁与乐观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时 ...

  7. 并发-AtomicInteger源码分析—基于CAS的乐观锁实现

    AtomicInteger源码分析—基于CAS的乐观锁实现 参考: http://www.importnew.com/22078.html https://www.cnblogs.com/mantu/ ...

  8. Spring IoC 源码分析 (基于注解) 之 包扫描

    在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫 ...

  9. CopyOnWriteArrayList源码分析

    基于jdk1.7源码 一.无锁容器 CopyOnWriteArrayList是JDK5中添加的新的容器,除此之外,还有CopyOnWriteArraySet.ConcurrentHahshMap和Co ...

随机推荐

  1. C#中一行代码实现18位数字时间戳转换为DateTime

    场景 存取的时间戳数据为: 636728674347302002 怎样将其转换为DateTime时间. 目前大多数的策略是,转换成string,然后 DateTime dateTimeStart = ...

  2. php中mysqli_error($conn)的用法

    注意:用函数判断sql语句是否有错需要把这个函数写在mysqli_query("$conn连接语句","$sql语句")后面才能进行检测. 返回值:返回最近调用 ...

  3. SparkStreming中 `transform()`算子的 的使用

    关联 DStream 和 RDD transform(func) Return a new DStream by applying a RDD-to-RDD function to every RDD ...

  4. 10.Redis 主从架构

    作者:中华石杉 Redis 主从架构 单机的 redis,能够承载的 QPS 大概就在上万到几万不等.对于缓存来说,一般都是用来支撑读高并发的.因此架构做成主从(master-slave)架构,一主多 ...

  5. EM算法直观认识

    Expectation Maximization, 字面翻译为, "最大期望". 我个人其实一直都不太理解EM算法, 从我个人的渊源来看, 之前数理统计里面的参数估计, 也是没有太 ...

  6. 【MongoDB详细使用教程】三、高级查询

    目录 1.使用比较运算符查询 2.使用关键字查询 2.1.in/not in 关键字 2.2.size 关键字 2.3.exists 关键字 2.4.or 关键字 3.模糊查询 4.查询结果排序 5. ...

  7. SpringBoot整合Fastdfs,实现图片上传(IDEA)

    我们部署Fastdfs,就是为了实现文件的上传. 现在使用idea整合Fastdfs,实现图片上传 部署环境:Centos7部署分布式文件存储(Fastdfs) 利用Java客户端调用FastDFS ...

  8. hydra使用,实例介绍

    hydra 是一个网络帐号破解工具,支持多种协议.其作者是van Hauser,David Maciejak与其共同维护.hydra在所有支持GCC的平台能很好的编译,包括Linux,所有版本的BSD ...

  9. git使用笔记(第一次)

    背景:公司基于微服务的架构,前端的服务web只有一个.在并行完成不同需求的测试任务时,该服务会拉出不同分支,此时会碰到sit环境与其他测试小伙伴部署冲突的问题.解释下.需求1对应的服务web的A分支, ...

  10. c# 第六节 c#的程序结构,以及vs的文件结构

    本节内容: 1:c#的程序结构 2:深入了解vs的文件 1:c#的程序结构 实例: 2:深入了解vs的文件 三者的关系: 3:命令空间是什么 使用别名: