CopyOnWriteArraySet
是线程安全的无序集合,它是通过聚合了一个CopyOnWriteArray
成员变量来实现的。
CopyOnWriteArraySet
是线程安全的无序集合,可以将它理解成线程安全的HashSet。有意思的是,CopyOnWriteArraySet
和HashSet虽然都继承于共同的父类AbstractSet;但是,HashSet是通过"散列表(HashSet)"实现的,而CopyConWriteArraySet则是通过"动态数组(CopyOnWriteArrayList)"实现的,并不是散列表。
CopyOnWriteArraySet
具有以下特性:
本文基于JDK1.7.0_67
java version "1.7.0_67"_
_Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
CopyOnWriteArraySet的数据结构,如下图所示:
图
说明
CopyOnWriteArraySet只有下面一个成员变量
private final CopyOnWriteArrayList<E> al;
说明:
final
类型的,通过构造函数进行初始化后将不能再修改。添加/修改/删除
操作都是通过互斥锁和volatile变量来保证现场安全的,因此,成员变量al不再用volatile
修饰,也不再额外声明可重入锁lock。// 创建一个空 set。
CopyOnWriteArraySet()
// 创建一个包含指定 collection 所有元素的 set。
CopyOnWriteArraySet(Collection<? extends E> c)
// 如果指定元素并不存在于此 set 中,则添加它。
boolean add(E e)
// 如果此 set 中没有指定 collection 中的所有元素,则将它们都添加到此 set 中。
boolean addAll(Collection<? extends E> c)
// 移除此 set 中的所有元素。
void clear()
// 如果此 set 包含指定元素,则返回 true。
boolean contains(Object o)
// 如果此 set 包含指定 collection 的所有元素,则返回 true。
boolean containsAll(Collection<?> c)
// 比较指定对象与此 set 的相等性。
boolean equals(Object o)
// 如果此 set 不包含任何元素,则返回 true。
boolean isEmpty()
// 返回按照元素添加顺序在此 set 中包含的元素上进行迭代的迭代器。
Iterator<E> iterator()
// 如果指定元素存在于此 set 中,则将其移除。
boolean remove(Object o)
// 移除此 set 中包含在指定 collection 中的所有元素。
boolean removeAll(Collection<?> c)
// 仅保留此 set 中那些包含在指定 collection 中的元素。
boolean retainAll(Collection<?> c)
// 返回此 set 中的元素数目。
int size()
// 返回一个包含此 set 所有元素的数组。
Object[] toArray()
// 返回一个包含此 set 所有元素的数组;返回数组的运行时类型是指定数组的类型。
<T> T[] toArray(T[] a)
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
public CopyOnWriteArraySet(Collection<? extends E> c) {
al = new CopyOnWriteArrayList<E>();
al.addAllAbsent(c);
}
CopyOnWriteArraySet允许初始化一个空的集合,也允许通过复制一个集合里的元素来进行初始化。本质上将,CopyOnWriteArraySet的初始化是通过初始化成员变量CopyOnWriteArrayList al来实现的。
public boolean add(E e) {
return al.addIfAbsent(e);
}
public boolean addAll(Collection<? extends E> c) {
return al.addAllAbsent(c) > 0;
}
CopyOnWriteArraySet不允许重复元素。因此,添加操作都是调用CopyOnWriteArrayList的addIfAbsent
方法或者addAllAbsent
方法实现的。