CopyOnWriteArrayList与CopyOnWriteArraySet详解

什么是CopyOnWrite容器

【1】CopyOnWrite容器是基于并发模式Copy-on-Write模式(最简单的并发解决方案)实现的用于避免共享的数据集合。

【2】CopyOnWrite容器又被成为写时复制的容器,即当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

【3】适用场景:读多写少的场景。

源码分析CopyOnWriteArrayList的实现

【1】属性说明

【2】方法解析(仅展示部分方法)

1)添加方法

2)设置方法

3)删除方法

4)获取方法

【3】汇总说明

1.CopyOnWriteArrayList之所以选择数组而不是链表作为变量的存储空间的原因:

1)提高处理速度,因为数组存储在内存中一块连续的空间,而链表则是分散的,采用Arrays.copyOf 本质上底层还是使用 System.arraycopy 将那块连续的内存空间的数据一次性拷贝,减少操作次数。

2.由源码可以看到,每次进行修改的时候都会加锁仅限于一个线程进行变更操作,避免了共享变量并发写的问题。所以是线程安全的。

3.但是其占用内存空间容易出现问题,如:在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象(注意:在复制的时候只是复制容器里的引用,只是在写的时候会创建新对象添加到新容器里,而旧容器的对象还在使用,所以有两份对象内存)。如果这些对象占用的内存比较大,比如说200M左右,那么再写入100M数据进去,内存就会占用300M,那么这个时候很有可能造成频繁的Yong GC和Full GC。而Full GC过长则应用响应时间也随之变长。

4.数据一致性问题,我们可以看出数据并不是实时一致性的,而是最终一致性。因为会先将数据拷贝到newElements 中,再设置到array的指针指向。要知道操作系统是基于时间片轮转机制分配运行时间(如:时间耗尽没有新的时间片给予,会导致线程上下文切换),所以中间的间隔时间可以假设很长,那么修改是写入了,但是变更还没进行。其次,在加锁的时间内,其他线程读取的其实都是没有修改的数据。

源码分析CopyOnWriteArraySet的实现

【1】属性说明

【2】方法说明

【3】汇总说明

1.CopyOnWriteArraySet的实现严格来说是基于CopyOnWriteArrayList进行实现的,去重逻辑在add中体现。

2.其次是效率问题:每次插入都需要去遍历CopyOnWriteArrayList数组一次。

3.虽然也是线程安全的,但是CopyOnWriteArrayList的缺点全部都会继承。

Original: https://www.cnblogs.com/chafry/p/16770916.html
Author: 忧愁的chafry
Title: CopyOnWriteArrayList与CopyOnWriteArraySet详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/712640/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球