CopyOnWriteArrayList 类分析
 
1. CopyOnWriteArrayList 其中底层实现存放数据是一个Object数组:
 
private volatile transient Object[] array;
 
2. CopyOnWriteArrayList 集合操作,当对集合中的元素进行修改添加或者替换删除(增删改)的时候都是用一个全局的 ReentrantLock lock锁进行控制线程安全的:
 
transient finall ReentrantLock lock = new ReentrantLock();
 
3. 创建其对象,默认设置一个长度为0的数组,赋值给array变量。
 
public CopyOnWriteArrayList() {
  setArray(new Object[0]);
}
 
4. 每次添加元素都创建一个新的数组,将原数组的数据复制到新的数组中,将新添加的元素放在新数组的末尾,重新将新数组赋值给 array , 代码如下:

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();
}
}
5. 因为存放数据的Object[] array 为volatile 类型的,所以在取数据的时候,没有加 lock锁。
 
6. 在此类中set方法中涉及到 happens-before 原则的代码如下:
public E set(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
E oldValue = get(elements, index); if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
关键代码在else代码块,重新到主内存中取了次链表中的元素。
 
7. 相关类CopyOnWriteArraySet内部实现是一个CopyOnWriteArrayList,代码如下:
   private final CopyOnWriteArrayList<E> al;

    /**
* Creates an empty set.
*/
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}

完。。。

Java集合(一) CopyOnWriteArrayList的更多相关文章

  1. 死磕 java集合之CopyOnWriteArrayList源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 CopyOnWriteArrayList是ArrayList的线程安全版本,内部也是通过 ...

  2. 死磕 java集合之CopyOnWriteArraySet源码分析——内含巧妙设计

    问题 (1)CopyOnWriteArraySet是用Map实现的吗? (2)CopyOnWriteArraySet是有序的吗? (3)CopyOnWriteArraySet是并发安全的吗? (4)C ...

  3. 死磕 java集合之终结篇

    概览 我们先来看一看java中所有集合的类关系图. 这里面的类太多了,请放大看,如果放大还看不清,请再放大看,如果还是看不清,请放弃. 我们下面主要分成五个部分来逐个击破. List List中的元素 ...

  4. Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)

    概要 前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例 ...

  5. Java集合面试题

    1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1 ...

  6. Java集合源码分析(二)ArrayList

    ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...

  7. Java集合系列:-----------04fail-fast总结(通过ArrayList来说明fail-fast的原理以及解决办法)

    前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例3 f ...

  8. Java集合容器简介

    Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...

  9. Java集合---ArrayList的实现原理

    目录: 一. ArrayList概述 二. ArrayList的实现 1) 私有属性 2) 构造方法 3) 元素存储 4) 元素读取 5) 元素删除                 6) 调整数组容量 ...

  10. Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

随机推荐

  1. GC 基础(转)

    转自:http://blog.csdn.net/ning109314/article/details/10411495/ = GC 基础 ===================== JAVA堆的描述如 ...

  2. 验证 Swarm 数据持久性 - 每天5分钟玩转 Docker 容器技术(104)

    上一节我们成功将 Rex-Ray Volume 挂载到了 Service.本节验证 Failover 时,数据不会丢失. Scale Up 增加一个副本: docker service update ...

  3. mysql读写分离的操作动作依据(读写分离基本依据)

    读的操作: 1.select 2.show 3.explain explain显示了MySQL如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 4.desc ...

  4. sublime text 3 ctrl+b浏览器启动html

    sublime text 2 和3 都可以快速设置浏览器启动,本人在这里介绍如何不下插件启动浏览器.第一步:打开Tool-->build system  ---> new build sy ...

  5. webpack loader加载器

    配置loader,通过加载器处理文件,例如css sass less等,告诉webpack每一种文件都需要使用什么来加载器来处理. 1.node.js安装好之后也会自动默认安装好npm,所以cmd c ...

  6. CS Round#53 C Histogram Partition

    题意:给定一个数组A,以及一个初始值全为0的空数组B,每次可以对数组B的任意一个区间内的所有数+x,问至少几次操作能把B数组变成A数组 NOIP原题(积木大赛)升级版,话说CS怎么那么多跟NOIP原题 ...

  7. 实践作业3:白盒测试----我是如何写测试用例DAY6

    一开始接到写白盒测试的任务,我感觉挺难的,因为感觉之前我所想到的都是黑盒测试啊,说到测试系统逻辑,感觉就有些神秘的样子没有思路了,那黑盒和白盒写的到底有啥区别.后来我请教了实验室的一个同学,他虽然还没 ...

  8. dict.get()和dict['key']的区别

    a ={'name':'xxxx'} 1.a.get('gender') :如果不存在则返回一个默认值,如果设置了则返回默认的值,没有设置就返回None 2.a['gender'] :只能获取存在的值 ...

  9. Scala入门系列(十三):类型参数

    引言 Scala中类型参数是什么呢?其实就类似于Java中的泛型.定义一种类型参数,比如在集合.类.函数中定义类型参数,然后就可以保证使用到该类型参数的地方就只能是这种类型,从而实现程序更好的健壮性. ...

  10. mysql本地訪问linuxserver,出现SQLSTATE[HY000] [1130] Host &#39;127.0.0.1&#39; is not allowed to connect to this

    解决方式:网上看了说.更改mysql库的user表,加入一条host为%的数据就能够.可是还是不行. 后来,直接登录mysql.给訪问加权限就能够了. 运行 [root@iZ25p77kem7Z ~] ...