CopyOnWriteArrayList使用
1、在遍历操作数量大大超过可变操作是(add,set等等)使用。原因是其可变操作是通过对底层数据进行一次新的复制来实现的。
2、迭代器创建后,其不会反应列表的添加、移除或更改。其迭代器是”快照“风格的,其创建使用了对数组状态的引用,此数组在迭代器的生存期内不会更改;如在迭代器上进行元素更改操(remove、set、add)作,将会抛出UnsupportedOperationException.
3、内存一致性效果:当存在其他并发 collection 时,将对象放入 CopyOnWriteArrayList
之前的线程中的操作 happen-before 随后通过另一线程从 CopyOnWriteArrayList
中访问或移除该元素的操作。
4、在进行并发编程时,跳异常:
Caused by: java.lang.ClassCastException: java.util.concurrent.CopyOnWriteArrayList$COWSubList cannot be cast to java.util.concurrent.CopyOnWriteArrayList
一开始觉得很奇怪,细看后问题出在:
CopyOnWriteArrayList<Long> list;
.....
CopyOnWriteArrayList<Long> list1= (CopyOnWriteArrayList<Long>)list.subList(i*len, ((i+1)*len>list.size())?(list.size()):((i+1)*len));
一方面使用了subList()子函数返回List<E>,得进行类型转换;另一方面该函数返回列表list的部分视图,返回列表list1受list支持,list已经为CopyOnWriteArrayList。这就导致矛盾,也就导致上面奇怪的报错!
修改方法为:
CopyOnWriteArrayList<Long> list1= new CopyOnWriteArrayList<Long>(); //重新创建一个CopyOnWriteArrayList,而不是原列表视图,如果需要列表修改反应到原列表上,那就不能使用subList函数了
list1.addAll(list.subList(i*len, ((i+1)*len>list.size())?(list.size()):((i+1)*len)));//
注意:如果通过返回列表以外的其他任何方式从结构上修改 底层实现列表(如上list),则此方法返回的列表语义将是不确定的。(从结构上修改是指更改列表的大小,或者以其他方式打乱列表,使正在进行的迭代生成错误的结果。)
CopyOnWriteArrayList使用的更多相关文章
- 【JUC】JDK1.8源码分析之CopyOnWriteArrayList(六)
一.前言 由于Deque与Queue有很大的相似性,Deque为双端队列,队列头部和尾部都可以进行入队列和出队列的操作,所以不再介绍Deque,感兴趣的读者可以自行阅读源码,相信偶了Queue源码的分 ...
- JAVA 多线程随笔 (三) 多线程用到的并发容器 (ConcurrentHashMap,CopyOnWriteArrayList, CopyOnWriteArraySet)
1.引言 在多线程的环境中,如果想要使用容器类,就需要注意所使用的容器类是否是线程安全的.在最早开始,人们一般都在使用同步容器(Vector,HashTable),其基本的原理,就是针对容器的每一个操 ...
- Java CopyOnWriteArrayList
1. 为什么需要 CopyOnWriteArrayList ArrayList 的内部实现是一个数组, 并且是动态扩容的, 当插入数据时, 先判断数组是否需要扩容, 如果需要扩容, 则先扩容, 再插入 ...
- 图解集合3:CopyOnWriteArrayList
初识CopyOnWriteArrayList 第一次见到CopyOnWriteArrayList,是在研究JDBC的时候,每一个数据库的Driver都是维护在一个CopyOnWriteArrayLis ...
- 如何线程安全地遍历List:Vector、CopyOnWriteArrayList
遍历List的多种方式 在讲如何线程安全地遍历List之前,先看看通常我们遍历一个List会采用哪些方式. 方式一: for(int i = 0; i < list.size(); i++) { ...
- Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList
概要 本章是"JUC系列"的CopyOnWriteArrayList篇.接下来,会先对CopyOnWriteArrayList进行基本介绍,然后再说明它的原理,接着通过代码去分析, ...
- java并发编程:并发容器之CopyOnWriteArrayList(转)
原文:http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开大家都在共享同一个内容,当某个 ...
- Java并发编程:并发容器之CopyOnWriteArrayList(转载)
Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...
- 集合迭代器快速失败行为及CopyOnWriteArrayList
以下内容基于jdk1.7.0_79源码: 什么是集合迭代器快速失败行为 以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入.移除...),而另一个线程 ...
- hash-6.CopyOnWriteArrayList
1.ArrayList的add方法 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount ...
随机推荐
- springboot(二十二)-sharding-jdbc-读写分离
前面我们使用sharding-jdbc配置了分库分表.sharding-jdbc还有个用法,就是实现读写分离. 什么时候需要或者可以使用读写分离? 当我们的项目所使用的数据库查询的访问量,访问频率,及 ...
- new angular 项目的工作区配置文件和应用源文件
1.工作区配置文件 每个工作空间中的所有项目共享同一个 CLI 配置环境 .该工作空间的顶层包含着全工作空间级的配置文件.根应用的配置文件以及一些包含根应用的源文件和测试文件的子文件夹. 工作空间配置 ...
- java中的Enum在@RestController(@ResponseBody) 注解下返回的表现
参考文档 枚举 public enum CouponType { PLATFORM("平台优惠券"), NEWCOMER("新人专享优惠券"), INVITE( ...
- Oracle VM VirtualBox 安装 Centos7 并配置静态IP
新建虚拟电脑 选择类型和版本 设置内存大小 现在创建虚拟硬盘 选择VDI 硬盘足够就选择 固定大小 选择虚拟硬盘存储位置不要放在默认的C盘下,设置大小为30G 等待创建虚拟硬盘 虚拟硬盘创建成果之后 ...
- hive元数据库理解
在hive2.1.1 里面一共有59张表 表1 VERSION ; version表存hive的版本信息,该表中数据只有一条,如果存在多条,会造成hive启动不起来. 表2 DBS select * ...
- CentOS7搭建FastDFS V5.11分布式文件系统(二)
1.CentOS7 FastDFS搭建 前面已下载好了要用到的工具集,下面就可以开始安装了: 如果安装过程中出现问题,可以下载我提供的,当前测试可以通过的工具包: 点这里点这里 1.1 安装libfa ...
- 通用mapper将另外一个同名的表生成在同一个实体及mapper中
今天遇见了一个在网上都搜索不到的错误,使用通过mapper生成实体及mapper文件时会将另外一个数据库的同名文件生成在一个实体及mapper中,这样就会造成一个实体和mapper中有两个表的字段,经 ...
- [HDU 3521] [最小割] Being a Hero
题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...
- Linux 指令总结
1. 显示本机信息 显示ip地址 hostname -i 显示当前使用用户 whoani 显示cpu信息 lscpu
- git中working tree, index, commit
这三个名字可以简单理解为文件在本地仓库存在的三种不同的位置. 如下,是做commit提交两段提交过程,工作区(working tree),暂存区(index)和 branch(commit). wor ...