CopyOnWriteArrayList&Collections.synchronizedList()
1、ArrayList
ArrayList是非线性安全,此类的 iterator() 和 listIterator() 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。即在一方在遍历列表,而另一方在修改列表时,会报ConcurrentModificationException错误。而这不是唯一的并发时容易发生的错误,在多线程进行插入操作时,由于没有进行同步操作,容易丢失数据。
2、CopyOnWriteArrayList
CopyOnWriteArrayList的add和remove方法是同步的(防止多个线程写操作时出现多个副本),每次修改都会创建并发布一个副本,get方法则不是同步的。看以下源码。该类的add、remove方法不具备原子性,所以一个在写,另一个线程在读到的数据可能是修改前的数据。


优点:多个线程可以同时对这个容器进行迭代,而不会相互干扰或者与修改容器的线程互相干扰,即不会抛出ConcurrentModificationException,并且返回的元素与迭代器创建时的元素完全一致,而不必考虑之后修改带来的影响。
缺点:1、在添加元素时会创建副本,如果副本占用内较大,会增加gc,严重可能会影响相应时间。2、数据只能保证最终一致性,无法保证实时性,可能读到的还是老的数据。
适用场景:适用于读多写少,并且对数据得一致性要求不高。
3、Collections.synchronizedList()


看看源码我们知道,Collections.synchronizedList()事实上是采用静态代理的方式进行操作,它的每个方法都是同步的,这样保证了列表操作都是线程安全的。相对于CopyOnWriteArrayList,Collections.synchronizedList()的在多个线程中写操作较快,读慢。
4、CopyOnWriteArrayList和Collections.synchronizedList()代码实测。
1)写
public class Test {
public static void main(String[] args) {
List<String> list1 = new CopyOnWriteArrayList<String>();
List<String> list2 = Collections.synchronizedList(new ArrayList<String>());
int count = 100;
long time1 = System.currentTimeMillis();
while (System.currentTimeMillis() - time1 < count) {
list1.add("1");
}
System.gc();
long time2 = System.currentTimeMillis();
while (System.currentTimeMillis() - time2 < count) {
list2.add("1");
}
System.out.println("CopyOnWriteArrayList在" + count + "毫秒时间内添加元素个数为: " + list1.size());
System.out.println("Collections.synchronizedList()在" + count + "毫秒时间内添加元素个数为: " + list2.size());
}
}
执行结果:
CopyOnWriteArrayList在100毫秒时间内添加元素个数为: 7987
Collections.synchronizedList()在100毫秒时间内添加元素个数为: 3027757
CopyOnWriteArrayList&Collections.synchronizedList()的更多相关文章
- CopyOnWriteArrayList与Collections.synchronizedList的性能对比
列表实现有ArrayList.Vector.CopyOnWriteArrayList.Collections.synchronizedList(list)四种方式. 1 ArrayList Array ...
- CopyOnWriteArrayList与Collections.synchronizedList的性能对比(转)
列表实现有ArrayList.Vector.CopyOnWriteArrayList.Collections.synchronizedList(list)四种方式. 1 ArrayList Array ...
- Collections.synchronizedList与CopyOnWriteArrayList比较
1.单线程方式 2.多线程版本,不安全的 ArrayList 3.多线程版本,线程安全,CopyOnWriteArrayList()方式 4.多线程版本,线程安全,Collections.synchr ...
- Collections.synchronizedList 、CopyOnWriteArrayList、Vector介绍、源码浅析与性能对比
## ArrayList线程安全问题 众所周知,`ArrayList`不是线程安全的,在并发场景使用`ArrayList`可能会导致add内容为null,迭代时并发修改list内容抛`Concurre ...
- ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 以及 同步的集合类 Hashtable 和 Vector Collections.synchronizedMap 和 Collections.synchronizedList 区别缺点
ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含 ...
- 集合不安全之 ArrayList及其三种解决方案【CopyOnWriteArrayList 、synchronizedList、Vector 】
@ 目录 一.前言 二.为什么线程不安全 三.解决方案一CopyOnWriteArrayList (推荐,读多写少场景) 四.Collections.synchronizedList(加锁) 五.Ve ...
- Collections.synchronizedList线程安全性陷阱
摘要: 详细的解析:Collections.synchronizedList 1 :关注要点,为什么在有synchroniezed方法的同时会出现 Collections.synchronizedLi ...
- 【集合类型的并发】Collections.synchronizedList
摘要: 详细的解析:Collections.synchronizedList :关注要点,为什么在有synchroniezed方法的同时会出现 Collections.synchronizedList ...
- Collections.synchronizedList使用
1.SynchronizedList类具体代码: static class SynchronizedList<E> extends SynchronizedCollection<E& ...
随机推荐
- oracle_18c新建用户用normal登陆失败
工具介绍:win10系统,使用的是oracle18c. 首先说一下oracle18c的特性,在oracle18c创建用户要以c##开头,比如: --创建新用户create user c##test_u ...
- DTCC2019第十届中国数据库技术大会将于5月在北京召开
作为国内顶级的数据领域技术盛会,10年来,DTCC见证了国内数据库技术的迅猛发展,各种分布式数据库.NoSQL.NewSQL技术异军突起,与Oracle.DB2等分庭抗礼,甚至大有超越之势.在这种背景 ...
- Eclipse出现:An internal error occurred during: "Retrieving archetypes:". GC overhead limit exceeded的问题解决
网上说修改虚拟内存的方式,其实不太可行,最直接的方式就是删除以前的workspace,重新使用一个新的workspace.
- windows程序设计 MessageBox消息框
MessageBox函数 int WINAPI MessageBoxW( HWND hWnd,//窗口句柄 LPCWSTR lpText,//消息框主体显示的字符串 LPCWSTR lpCaption ...
- caffe-ssd的GPU在make runtest的时候报错:BatchReindexLayerTest/2.TestGradient,where TypeParam=caffe::GPUdevice(<float>)(<double>)
make runtest报错:BatchReindexLayerTest/2.TestGradient,where TypeParam=caffe::GPUdevice<float> Ba ...
- Delphi7打开项目提示'one or more lines were too long and has been truncated'
打开主项目文件直接显示一排'口'形状!查了下资料也问了下伙伴,这多半应该是文件损坏了,解决办法: 1. 不关D7的事,所以重装D7应该是无效的,最好看看自己是不是有备份文件,我之前有备份的所以直接覆盖 ...
- HTML基础教程
<!DOCTYPE html><html> <head> <title></title> </head> <body> ...
- spring bean的初始化以及销毁
spring bean初始化或销毁时执行某些方法,有很多使用场景.比如初始化时,启动bean中的线程池.销毁时释放资源,个人比较喜欢实现InitializingBean和 DisposableBean ...
- easyUI 创建详情页dialog
使用easyui dialog先下载jQuery easyui 的压缩包 下载地址http://www.jeasyui.com/download/v155.php 解压后放在项目WebContent ...
- 用Java画简单验证码
以下是具体代码: package com.jinzhi.tes2; import java.awt.Color;import java.awt.Font;import java.awt.Graphic ...