Java并发之CopyOnWriteArrayList
CopyOnWriteArrayList是线程安全的、并且读操作无锁的ArrayList。
不像ArrayList默认初始化大小为10的Object[],CopyOnWriteArrayList默认初始化大小为0的Object[]
1,add(E)
add方法没有给整个方法加synchronized关键字,而是使用ReentrantLock来保证线程安全。
该方法和ArrayList的add方法不同,ArrayList在add时候如果List中元素个数超出Object[]大小,则扩容,默认扩容1.5倍,而CopyOnWriteArrayList是新创建一个比原来大1的数组,然后将新元素放在最后。
2,remove(E)
在ArrayList的remove方法中,代码如下:
public E remove(int index) {
...
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
从代码可以看出,ArrayList是直接操作原数组,利用 System.arraycopy将index之后的元素往前挪。
而在CopyOnWriteArrayList的remove中,和add方法一样,也是通过ReentrantLock保证线程安全,代码如下:
public E remove(int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object oldValue = 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 (E)oldValue;
} finally {
lock.unlock();
}
}
从代码可以看出,CopyOnWriteArrayList新创建了一个大小比原来小1的新数组,然后利用System.arraycopy将原数组index前后分两次拷贝至新数组。
Java并发之CopyOnWriteArrayList的更多相关文章
- java并发之CopyOnWriteArraySet
java并发之CopyOnWriteArraySet CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的,持有CopyOnWriteArrayList的内部对象 ...
- java并发之CopyOnWirteArrayList
java并发之CopyOnWirteArrayList CopyOnWirteArrayList的实现 它用了ReentrantLock保证了add,set,remove操作的安全,同时使用volat ...
- java.util.concurrent.CopyOnWriteArrayList
import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; impo ...
- java并发之固定对象与实例
java并发之固定对象与实例 Immutable Objects An object is considered immutable if its state cannot change after ...
- Java并发之BlockingQueue的使用
Java并发之BlockingQueue的使用 一.简介 前段时间看到有些朋友在网上发了一道面试题,题目的大意就是:有两个线程A,B, A线程每200ms就生成一个[0,100]之间的随机数, B线 ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- Java并发之Semaphore的使用
Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...
- Java并发之CyclicBarria的使用(二)
Java并发之CyclicBarria的使用(二) 一.简介 之前借助于其他大神写过一篇关于CyclicBarria用法的博文,但是内心总是感觉丝丝的愧疚,因为笔者喜欢原创,而不喜欢去转载一些其他的文 ...
- Java并发之CyclicBarria的使用
Java并发之CyclicBarria的使用 一.简介 笔者在写CountDownLatch这个类的时候,看到了博客园上的<浅析Java中CountDownLatch用法>这篇博文,为博主 ...
随机推荐
- nno_setup制作升级包必须面临的几个问题 2
这两天的时间一直在制作应用程序的升级包,期间碰到一些问题这里一并记录下来,相信这是制作升级包必须面临和解决的问题: 1. 升级包安装程序如何不再产生新的安装.卸载程序 Inno_setup中AppId ...
- 转:服务器控件的 ID,ClientID,UniqueID 的区别
动态加载用户控件的怪问题 动态加载用户控件的时候,会因为调用一些控件的一些属性和方法而造成控件命名混乱. 因为add 一个用户控件或者 loadcontrol 的时候 如果没有指定控件的id,clie ...
- 用UltralSO安装CentOS 和 Ubuntu
UltralSO是一个U盘制作工具,这几天用UltralSO安装了CentOS和Ubuntu 制作这两个U盘启动程序的区别是,CentOS安装完后,需要把.iso文件拷贝到U盘中,而且CentOS文件 ...
- (实用篇)PHP页面跳转到另一个页面的方法总结
一.用HTTP头信息 也就是用PHP的header函数.PHP里的header函数的作用就是向浏览器发出由HTTP协议规定的本来应该通过WEB服务器的控制指令,例如声明返回信息的类型("C ...
- Highcharts入门+Highcharts基础教程,【非常值得学习的资料】
http://www.hcharts.cn/docs/index.php?doc=index Highcharts入门章节目录 Highcharts简介 Highcharts下载与使用 Highcha ...
- matlab演奏最炫民族风的代码注释
用Matlab来放音乐,和用单片机加蜂鸣器放音乐的原理都差不多,就是把连续的声音信号事先转换成用数字信号,然后用扬声器按照一定的节奏放出来.换句话说,演唱者是把声音经过麦克风转换成电信号,录音设备对这 ...
- canvas-绘制时钟
把最近学到的一些canvas技能全部发上来,刚开始写博客,感觉还不太习惯,不过我相信慢慢就会习惯了.不啰嗦了,把代码送上,看不懂的话可以先去学习下基础教程,把基础学好了也就能看懂了. <!DOC ...
- Android加载网络图片的工具类
ImageView加载网络的图片 HttpUtil.java package com.eiice.httpuimagetils; import java.io.ByteArrayOutputStrea ...
- [转] shiro简单配置
shiro(1) 注:这里只介绍spring配置模式. 因为官方例子虽然中有更加简洁的ini配置形式,但是使用ini配置无法与spring整合.而且两种配置方法一样,只是格式不一样. 涉及的jar包 ...
- [AHOI 2006][BZOJ 1269]文本编辑器editor
好吧,我承认这是我用来刷随笔数的喵~ 这是一道 splay 裸题,但还是有想本傻 X 一样根本不会写 splay 的,于是乎又用 treap 水过了 splay 的常数我还是知道的,所以真是不知道那些 ...