并发容器-CopyOnWriteArrayList

1 /** The array, accessed only via getArray/setArray. */
2 private transient volatile Object[] array;
1 /**
2 * {@inheritDoc}
3 *
4 * @throws IndexOutOfBoundsException {@inheritDoc}
5 */
6 public E get(int index) {
7 return get(getArray(), index);
8 }
9 /**
10 * Gets the array. Non-private so as to also be accessible
11 * from CopyOnWriteArraySet class.
12 */
13 final Object[] getArray() {
14 return array;
15 }
16 @SuppressWarnings("unchecked")
17 private E get(Object[] a, int index) {
18 return (E) a[index];
19 }
1 /**
2 * Replaces the element at the specified position in this list with the
3 * specified element.
4 *
5 * @throws IndexOutOfBoundsException {@inheritDoc}
6 */
7 public E set(int index, E element) {
8 final ReentrantLock lock = this.lock;
9 lock.lock();
10 try {
11 Object[] elements = getArray();
12 E oldValue = get(elements, index);
13 // 判断原有位置元素是否和插入元素相同,不相同才插入
14 if (oldValue != element) {
15 int len = elements.length;
16 Object[] newElements = Arrays.copyOf(elements, len);
17 newElements[index] = element;
18 setArray(newElements);
19 } else {
20 // Not quite a no-op; ensures volatile write semantics
21 // 不是无用操作,是为了保证volatile写的意义
22 setArray(elements);
23 }
24 return oldValue;
25 } finally {
26 lock.unlock();
27 }
28 }
29 /**
30 * Sets the array.
31 */
32 final void setArray(Object[] a) {
33 array = a;
34 }
// initial conditions
int nonVolatileField = 0;
CopyOnWriteArrayList<String> list = /* a single String */ // Thread 1
nonVolatileField = 1; // (1)
list.set(0, "x"); // (2) // Thread 2
String s = list.get(0); // (3)
if (s == "x") {
int localVar = nonVolatileField; // (4)
}
1 /**
2 * Appends the specified element to the end of this list.
3 * 末尾增加元素
4 * @param e element to be appended to this list
5 * @return {@code true} (as specified by {@link Collection#add})
6 */
7 public boolean add(E e) {
8 final ReentrantLock lock = this.lock;
9 lock.lock();
10 try {
11 Object[] elements = getArray();
12 int len = elements.length;
13 Object[] newElements = Arrays.copyOf(elements, len + 1);
14 newElements[len] = e;
15 setArray(newElements);
16 return true;
17 } finally {
18 lock.unlock();
19 }
20 }
21 /**
22 * Inserts the specified element at the specified position in this
23 * list. Shifts the element currently at that position (if any) and
24 * any subsequent elements to the right (adds one to their indices).
25 *
26 * @throws IndexOutOfBoundsException {@inheritDoc}
27 */
28 public void add(int index, E element) {
29 final ReentrantLock lock = this.lock;
30 lock.lock();
31 try {
32 Object[] elements = getArray();
33 int len = elements.length;
34 if (index > len || index < 0)
35 throw new IndexOutOfBoundsException("Index: "+index+
36 ", Size: "+len);
37 Object[] newElements;
38 int numMoved = len - index;
39 if (numMoved == 0)
40 newElements = Arrays.copyOf(elements, len + 1);
41 else {
42 newElements = new Object[len + 1];
43 System.arraycopy(elements, 0, newElements, 0, index);
44 System.arraycopy(elements, index, newElements, index + 1,
45 numMoved);
46 }
47 newElements[index] = element;
48 setArray(newElements);
49 } finally {
50 lock.unlock();
51 }
52 }
可以看到,增加元素和更新元素一样,也是创建一个新数组复制原有元素,然后插入新增元素。同时也是加了可重入锁,同一时刻只有一个线程能进行修改。
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices). Returns the element that was removed from the list.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
E oldValue = get(elements, index);
int numMoved = len - index - 1;
if (numMoved == 0)
setArray(Arrays.copyOf(elements, len - 1));
else {
Object[] newElements = new Object[len - 1];
System.arraycopy(elements, 0, newElements, 0, index);
System.arraycopy(elements, index + 1, newElements, index,
numMoved);
setArray(newElements);
}
return oldValue;
} finally {
lock.unlock();
}
}
并发容器-CopyOnWriteArrayList的更多相关文章
- Java并发编程原理与实战三十四:并发容器CopyOnWriteArrayList原理与使用
1.ArrayList的实现原理是怎样的呢? ------>例如:ArrayList本质是实现了一个可变长度的数组. 假如这个数组的长度为10,调用add方法的时候,下标会移动到下一位,当移动到 ...
- 多线程并发容器CopyOnWriteArrayList
原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...
- Java并发容器——CopyOnWriteArrayList
CopyOnWriteArrayList是“读写分离”的容器,在写的时候是先将底层源数组复制到新数组中,然后在新数组中写,写完后更新源数组.而读只是在源数组上读.也就是,读和写是分离的.由于,写的时候 ...
- Java并发机制(5)--同步容器与并发容器
Java并发编程:同步容器整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3933404.html1.同步容器出现原因 常用的ArrayList,Lin ...
- JAVA 多线程随笔 (三) 多线程用到的并发容器 (ConcurrentHashMap,CopyOnWriteArrayList, CopyOnWriteArraySet)
1.引言 在多线程的环境中,如果想要使用容器类,就需要注意所使用的容器类是否是线程安全的.在最早开始,人们一般都在使用同步容器(Vector,HashTable),其基本的原理,就是针对容器的每一个操 ...
- CopyOnWriteArrayList并发容器
CopyOnWriteArrayList并发容器 Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才 ...
- 09 jdk1.5的并发容器:CopyOnWriteArrayList(转载)
原文链接:http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略. 其基本思路是,从一开始大家都在共享同一个内容 ...
- 【java并发容器】并发容器之CopyOnWriteArrayList
原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...
- Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList
原文出处http://cmsblogs.com/ 『chenssy』 到目前为止,我们在Java世界里看到了两种实现key-value的数据结构:Hash.TreeMap,这两种数据结构各自都有着优缺 ...
随机推荐
- MyBatis-Plus【踩坑记录01】
不要使用Mybatis原生的SqlSessionFactory,而应使用MybatisSqlSessionFactory. 原因 依赖关系如下 因此会在使用Mybaits-Plus时默认的时Mybat ...
- P1047_校门外的树(JAVA语言)
题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米. 我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置: 数轴上的每个整数点,即0,1,2,-,L都种 ...
- UnboundLocalError: local variable 'foo' referenced before assignment Python常见错误
在定义局部变量前在函数中使用局部变量(此时有与局部变量同名的全局变量存在) 在函数中使用局部变来那个而同时又存在同名全局变量时是很复杂的, 使用规则:如果在函数中定义了任何东西,如果它只是在函数中使用 ...
- C++并发与多线程学习笔记--unique_lock详解
unique_lock 取代lock_quard unique_lock 的第二个参数 std::adopt_lock std::try_to_lock std::defer_lock unique_ ...
- [hash-bfs]USACO 3.2 Magic Squares 魔板
魔 板 魔板 魔板 题目描述 在成功地发明了魔方之后,拉比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色 ...
- 翻译:《实用的Python编程》07_05_Decorated_methods
目录 | 上一节 (7.4 装饰器) | 下一节 (8 测试和调试) 7.5 装饰方法 本节讨论一些与方法定义结合使用的内置装饰器. 预定义的装饰器 在类定义中,有许多预定义的装饰器用于指定特殊类型的 ...
- java面试-JVM调优和参数配置,如何查看JVM系统参数默认值
一.JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式(先编译后执行) -Xint 解释执行 -Xcomp 第一次使用就编译 ...
- 【CTF】CTFHub 技能树 文件头检查 writeup
PHP一句话木马 <?php @eval($_POST["pass"]);?> <?php eval($_REQUEST["pass"]);? ...
- Spring Security框架中踢人下线技术探索
1.背景 在某次项目的开发中,使用到了Spring Security权限框架进行后端权限开发的权限校验,底层集成Spring Session组件,非常方便的集成Redis进行分布式Session的会话 ...
- Magicodes.IE.ASPNETCore之多样化接口使用
1.安装包 Install-Package Magicodes.IE.AspNetCore 2.开始配置 在Startup.cs的Configure()方法中,在UseRouting()中间件之后,注 ...