概述
目录
- 一、CopyOnWrite 机制
- 二、CopyOnWriteArrayList
一、CopyOnWrite
机制
1、CopyOnWrite 原理
CopyOnWrite 简称 COW,翻译为写时复制,它是一种读写分离思想的应用。当我们对一个容器进行修改操作(添加、删除、编辑)时候,不会直接对当前容器修改,而是先将当前容器进行 Copy,复制出一个新的容器,然后在这个新的容器里进行修改元素的操作,而后面进行的读操作则继续在旧容器中读取。 修改完之后,再将原容器的引用指向新的容器,而旧的容器则进行垃圾回收。
写时复制只对修改操作进行加锁(写锁),而对于读操作则不进行加锁,这样的好处是即不会造成并发修改异常,也不会影响并发读取操作。
2、CopyOnWrite 适用的场景
从 CopyOnWrite 原理可以知道,写时复制只适合读多写少的场景,比如用户的白名单、黑名单等等。
3、CopyOnWrite 的优缺点
优点:
读写分离保证了读操作的并发不受影响,进行编辑操作操作会复制一份进行修改不会对影响旧的容器数据,因此不会抛出并发修改异常。
缺点:
- 占用内存: 由于进行写操作时会对旧数据进行复制一份,如果原先的数据比较大的话会占用比较多的内存,可能造成频繁的 Yong GC 和 Full GC。针对内存占用问题,可以考虑使用其他的并发容器,如 ConcurrentHashMap。
- 数据一致性问题: CopyOnWrite 容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用 CopyOnWrite 容器。
二、CopyOnWriteArrayList
1、ArrayList 遍历过程中删除的问题
当我们使用 forEach 遍历 ArrayList 时删除元素都会得到一个java.util.ConcurrentModificationException 的错误。这是因为在 ArrayList 的 remove() 方法中,有一个参数 modCount 专门用来记录修改的次数,每删除一次就 modCount++。在 forEach 遍历集合时,首先会记录 final int expectedModCount = modCount,若是遍历过程中发现 expectedModCount!=modCount,则会抛出错误。
所以使用 ArrayList 时,如果你有遍历删除某个元素的场景,我们可以使用迭代器来删除。
2、CopyOnWriteArrayList 的原理
CopyOnWriteArrayList 就是写时复制的一种应用,用来保证线程数据安全。在遍历 CopyOnWriteArrayList 的过程中,如果要对其进行编辑操作的话,会复制一份新的数组容器对象用于编辑操作,在此过程中的读操作在获取的是原先的旧容器上的数据。这样就避免了在遍历的时候进行修改操作时抛出并发修改异常问题。
当编辑操作完成之后就会将旧容器的引用指向新的容器中,旧容器则会进行垃圾回收。
值得注意的是: CopyOnWriteArrayList 的迭代器实现里的 remove() 方法会直接抛出异常,因此在使用迭代器遍历元素时,不能删除元素。
最后
以上就是无私白开水为你收集整理的【Java 集合】之 CopyOnWriteArrayList目录一、CopyOnWrite 机制二、CopyOnWriteArrayList的全部内容,希望文章能够帮你解决【Java 集合】之 CopyOnWriteArrayList目录一、CopyOnWrite 机制二、CopyOnWriteArrayList所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复