java并发——copyonwrite
今天在网上看到一个问题,问除了加锁之外,有没有其他方法来保证线程安全?
---- copyonwrite机制
一、copyonwrite机制
机制实现:写时复制, 在往集合中添加数据的时候,先拷贝存储的数组,然后添加元素到拷贝好的数组中,然后用现在的数组去替换成员变量的数组。
这个机制:和读写锁是一样的,但是比读写锁有改进的地方,那就是 读取的时候可以写入的 ,这样省去了读写之间的竞争。(同时写入怎么解决?----还是通过加锁)。
二、java中的copyonwrite
java中提供了两个利用这个机制实现的线程安全集合:
1、copyonwritearraylist
2、copyonwritearrayset (copyonwritearrayset的底层实现是copyonwritearraylist)
我们接下来看看java的实现。
public E get(int index) {
return get(getArray(), index);
}
private transient volatile Object[] array; //volatile声明的数组,保证了读取的那一刻是最新的数据
接下来重点就是add方法了。下面的代码可以明显看出是明显需要reentrantlock加锁的,
接下来就是复制数据和添加数据的过程,在setArray的过程中,把新的数组赋值给成员变量array(这里是引用的指向,java保证赋值的过程是一个原子操作)。
public void add(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+len);
Object[] newElements;
int numMoved = len - index;
if (numMoved == 0)
newElements = Arrays.copyOf(elements, len + 1);
else {
newElements = new Object[len + 1];
System.arraycopy(elements, 0, newElements, 0, index);
System.arraycopy(elements, index, newElements, index + 1,
numMoved);
}
newElements[index] = element;
setArray(newElements);
} finally {
lock.unlock();
}
}
关于迭代,他采取的是获取传递给迭代器的数组值进行迭代,中间就算加入新的值也迭代不到。在构造函数中就直接赋值给final的成员变量。
private final Object[] snapshot;
private COWIterator(Object[] elements, int initialCursor) {
cursor = initialCursor;
snapshot = elements;
}
适用场景
copyonwrite的机制虽然是线程安全的,但是在add操作的时候不停的拷贝是一件很费时的操作。
所以使用到这个集合的时候尽量不要出现频繁的添加操作,而且在迭代的时候,数据也是不及时的,数据量少还好说,数据太多的时候,实时性可能就差距很大了。
适合:在多读取,少添加的时候,他的效果还是不错的(数据量大无所谓,只要你不添加,他都是好用的)。
java并发——copyonwrite的更多相关文章
- Java并发编程:CopyOnWrite容器的实现
Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...
- Java并发集合的实现原理
本文简要介绍Java并发编程方面常用的类和集合,并介绍下其实现原理. AtomicInteger 可以用原子方式更新int值.类 AtomicBoolean.AtomicInteger.AtomicL ...
- java并发容器类
本文主要介绍java并发容器相关实现类,collections节点下接口方法介绍. Queue Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是Blocking ...
- Java并发编程:并发容器之CopyOnWriteArrayList(转载)
Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...
- Java并发编程:并发容器之CopyOnWriteArrayList
转载: Java并发编程:并发容器之CopyOnWriteArrayList Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个 ...
- Java 并发基础
Java 并发基础 标签 : Java基础 线程简述 线程是进程的执行部分,用来完成一定的任务; 线程拥有自己的堆栈,程序计数器和自己的局部变量,但不拥有系统资源, 他与其他线程共享父进程的共享资源及 ...
- java并发程序——并发容器
概述 java cocurrent包提供了很多并发容器,在提供并发控制的前提下,通过优化,提升性能.本文主要讨论常见的并发容器的实现机制和绝妙之处,但并不会对所有实现细节面面俱到. 为什么JUC需要提 ...
- Java 并发集合的实现原理
http://www.codeceo.com/article/the-implementation-principle-of-java-concurrent-collection.html 阿凡卢 ...
- 【转】Java并发编程:并发容器之CopyOnWriteArrayList
Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...
随机推荐
- [JavaWeb基础] 027.JAVA中使用Axis搭建webservice-示例实现(二)
在上面的一个文章中,我们介绍了如何搭建Axis2的环境,也就是在MyEclipse中加入Axis的开发插件,那么,准备工作做好了之后,下面我们就用上一章的工具去搭建一个WebService的简单例子. ...
- 善意的投票&小M的作物 题解
善意的投票: 因为只有\(2\)种意愿,不妨让想睡午觉的和源点连边,让不想睡午觉的和汇点连边.对于每一对好朋友,在他们之间连边.那么只要源点和汇点还联通,就存在一对好友是冲突的,我们现在要做的就是删去 ...
- css 盒模型、box-sizing 学习笔记
默认情况下,给元素设置的高度和宽度是元素内容区的宽度和高度,给元素加padding 和 border ,元素的实际宽度和高度的计算方式是下面的两个公式: 元素的宽度= 元素的内容区宽度 + 内边距宽度 ...
- Rocket - debug - Example: Triggers
https://mp.weixin.qq.com/s/zPNyrBOhsytkRrZTDTEvpw 介绍riscv-debug的使用实例:配置Triggers功能. 1. Trigger Trigge ...
- Chisel3 - util - Mux
https://mp.weixin.qq.com/s/TK1mHqvDpG9fbLJyNxJp-Q Mux相关电路生成器. 参考链接: https://github.com/freechips ...
- Java实现 LeetCode 769 最多能完成排序的块(单向遍历)
769. 最多能完成排序的块 数组arr是[0, 1, -, arr.length - 1]的一种排列,我们将这个数组分割成几个"块",并将这些块分别进行排序.之后再连接起来,使得 ...
- Java实现 LeetCode 662 二叉树最大宽度(递归)
662. 二叉树最大宽度 给定一个二叉树,编写一个函数来获取这个树的最大宽度.树的宽度是所有层中的最大宽度.这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空. 每一层的 ...
- Java实现蓝桥杯 历届试题 k倍区间
历届试题 k倍区间 时间限制:2.0s 内存限制:256.0MB 问题描述 给定一个长度为N的数列,A1, A2, - AN,如果其中一段连续的子序列Ai, Ai+1, - Aj(i <= j) ...
- Java实现高效便捷还容易懂的排序算法
PS:我现在越来越认为排序大法是,很深的算法了,就是简单的几个步骤,网上的大佬们能给你玩出花来(ง •_•)ง public class zimuzhenlie2 { public static vo ...
- java实现多线程(车站卖票)
import java.util.ArrayList; import java.util.List; public class 多线程 { // public static int j=0; publ ...