如果你了解这个集合,且清楚写时复制原理,可以直接跳到最后查看答案
什么是CopyOnWriteArrayList容器分为两大类:Collection和Map 就Map而言,其HashMap在多线程高并发场景下有ConcurrentHashMap来保障线程安全
那么JUC包下有支持list线程安全的容器吗?
首先呢Vector是线程安全的,但它的做法是直接在方法上加synchronized,这导致效率不高。 我们有很多场景是读多写少,写的时候可以加锁保证数据一致性,但是读的时候是没有必要加锁的。 因此CopyOnWriteArrayList和CopyOnWriteArraySet就产生了
它的读写锁的概念和ReentrantReadAndWriteLock的读写锁概念类似,即是读共享锁,写排他锁。但是CopyOnWriteArrayList更进一步的是,它连读都不加锁,并且一边写还能一边读,也就是说写不会阻塞读。这是怎么做到的呢?就要谈到CopyOnWrite写时复制机制,这个机制本身在linux系统底层和其他很多地方都有应用,比如redis的rdb持久化空间时fork子进程就用到了这个机制。
具体是直接把写入的数组拷贝一份,修改操作是在拷贝的副本中进行的,因此在原来对象上的读就不受影响。写完后再指向副本,这样原来的数组就会被GC回收了。并且CopyOnWriteArrayList在写入时的加锁是通过ReentrantLock实现的,即底层是CAS操作,性能上得到了提升。当然在jdk1.8之后synchronized的性能也得到了改善,并不比ReentrantLock差多少,而且官方也更加推荐使用synchronized
什么是fast-fail呢?即快速失败机制,是java集合中的一种错误检测机制。当使用迭代器Iterator迭代集合的过程中该集合在结构上发生变化时就有可能发生fail-fast,抛出ConcurrentModificationException异常,在不同步的修改并不一定会抛,只是尽量抛出异常
什么叫集合的结构发生变化?就是元素多了或者少了,如果只是修改了元素值结构并没有发生变化
List,HashMap迭代器都支持fast-fail,即迭代器迭代时容器结构发生变化都会抛出ConcurrentModificationException
CopyOnWriteArrayList的迭代器支持fast-fail吗?不支持! 因为写时复制的存在,CopyOnWriteArrayList在使用迭代器迭代的时候,实际上迭代的是原数组,而不是更新的数组,所以中间如果发生新增、删除元素是在新数组上发生的,所以不影响旧数组的迭代,但是正因为元素的迭代发生在旧数组上,所以迭代时更新的数据是获取不到最新的,存在时延。
测试:
@Test
public void test3(){
CopyOnWriteArrayList list = new CopyOnWriteArrayList();
for (int i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?