JUC 一 CopyOnWriteArrayList 和 CopyOnWriteArraySet
欢迎光临我的博客[http://poetize.cn],前端使用Vue2,聊天室使用Vue3,后台使用Spring Boot
java.util.concurrent;
简介
CopyOnWriteArrayList
是一个线程安全的ArrayList
,通过内部的volatile数组
和显式锁ReentrantLock
来实现线程安全。CopyOnWriteArraySet
是线程安全的Set
,它是由CopyOnWriteArrayList
实现,内部持有一个CopyOnWriteArrayList
引用,所有的操作都是由CopyOnWriteArrayList
来实现的,区别就是CopyOnWriteArraySet
是无序的,并且不允许存放重复值。
CopyOnWrite适用场景
- 适合元素比较少,并且读取操作高于更新(add/set/remove)操作的场景
- 由于每次更新需要复制内部数组,所以更新操作开销比较大
- 内部的迭代器 iterator 使用了“快照”技术,存储了内部数组快照, 所以它的 iterator 不支持remove、set、add操作,但是通过迭代器进行并发读取时效率很高。
CopyOnWriteArrayList源码(并发安全解决方案一)
/**
* The lock protecting all mutators. (We have a mild preference
* for builtin monitors over ReentrantLock when either will do.)
*/
final transient Object lock = new Object();
/** The array, accessed only via getArray/setArray. */
private transient volatile Object[] array;
/**
* Appends the specified element to the end of this list.
*/
public boolean add(E e) {
synchronized (lock) {
Object[] es = getArray();
int len = es.length;
es = Arrays.copyOf(es, len + 1);
es[len] = e;
setArray(es);
return true;
}
}
public E get(int index) {
return elementAt(getArray(), index);
}
ArrayList并发安全解决方案二
List<String> list = Collections.synchronizedList(new ArrayList<String>());
CopyOnWriteArraySet
线程安全的无序的集合,可以将它理解成线程安全的HashSet
CopyOnWriteArraySet(底层实现是利用数组,上层实现是CopyOnWriteArrayList),但不能有重复元素:
CopyOnWriteArrayList额外提供了addIfAbsent()和addAllAbsent()这两个添加元素的API,只有当元素不存在时才执行添加操作!
CopyOnWriteArraySet的“线程安全”机制,和CopyOnWriteArrayList一样,是通过volatile和互斥锁来实现的