前言
CopyOnWrite简称COW机制,是一种程序优化策略(延时懒惰策略).其思路是,一开始共享同一内容,当想对此内容进行修改时,会将此内容复制一份,对复制的内容进行修改,修改之后再将原内容的引用指向修改后的内容。
JDK5并发包提供使用了CopyOnWrite机制实现的并发容器(CopyOnWriteArrayList与CopyOnWriteArraySet),在并发场景中使用较多。
CopyOnWrite容器
写时复制的容器,当我们对容器进行操作时(添加删除元素等),不直接对原容器进行操作,而是将原容器复制一份,对新容器进行操作(操作副本),操作完再将原容器的引用指向新容器。
CopyOnWriteArrayList
CopyOnWriteArrayList是list接口的线程安全实现,属于java.util.concurrent包,是ArrayList的增强版(兼容ArrayList特性且线程安全)。
适用场景
读多写少
常用方法
package cn.tedu.scalapackage;
import java.util.Arrays;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @description: CopyOnWriteArrayList用法
* @author: zfh
* @email: hst1406959716@163.com
* @date: Created in 2021/6/9 12:09
* @modified By:
* @version: 1.0
*/
public class CopyOnWriteArrayListDemo {
public static void main(String[] args) {
CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList();
//isEmpty判空
System.out.println(copyOnWriteArrayList.isEmpty());
//size 长度
System.out.println(copyOnWriteArrayList.size());
System.out.println();
//add 添加 各种类型 元素可重复包括null
copyOnWriteArrayList.add("小生不才");
copyOnWriteArrayList.add(618);
// copyOnWriteArrayList.add(618);
copyOnWriteArrayList.add(null);
System.out.println(copyOnWriteArrayList.size());
System.out.println();
//get 获取指定索引位置的元素
System.out.println(copyOnWriteArrayList.get(1));
System.out.println();
//在指定索引位置添加元素
copyOnWriteArrayList.add(1,"齐雷");
System.out.println(copyOnWriteArrayList.get(1));
System.out.println(copyOnWriteArrayList.size());
System.out.println();
//addAll 添加所有
copyOnWriteArrayList.addAll(Arrays.asList("1",666,"刘昱江"));
System.out.println(copyOnWriteArrayList.size());
System.out.println();
//clear 清空
//copyOnWriteArrayList.clear();
System.out.println(copyOnWriteArrayList.size());
//contains 判断是否含有
System.out.println(copyOnWriteArrayList.contains("刘昱江"));
System.out.println();
//indexOf 指定元素的第一次索引位置
System.out.println(copyOnWriteArrayList.indexOf("小生不才"));
copyOnWriteArrayList.add("小生不才");
System.out.println(copyOnWriteArrayList.indexOf("小生不才"));
//lastIndexOf 指定元素的最后一次索引位置
System.out.println(copyOnWriteArrayList.lastIndexOf("小生不才"));
System.out.println();
//遍历 使用迭代器
Iterator iterator = copyOnWriteArrayList.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//遍历 foreach
System.out.println();
for (Object c: copyOnWriteArrayList ) {
System.out.println(c);
}
System.out.println();
System.out.println(copyOnWriteArrayList.get(1));
//删除指定索引位置的元素
copyOnWriteArrayList.remove(1);
System.out.println(copyOnWriteArrayList.get(1));
//删除指定元素
copyOnWriteArrayList.remove("齐雷");
System.out.println(copyOnWriteArrayList.contains("齐雷"));
}
}
总结
CopyOnWrite有很多优点,但也存在2个缺点。
-
内存占用问题
写时复制机制,在进行写操作时,内存中同时有2个对象(旧对象与新对象)的内存,可能造成频繁的Yong GC与Full GC。
-
数据一致性
只能保证数据的最终一致性,而不能保证数据的实时一致性。