CopyOnWriteArraySet
类图

CopyOnWriteArraySet
简介
CopyOnWriteArraySet
继承于 AbstractSet
,这就意味着它是一个集合。并且是线程安全的
CopyOnWriteArraySet
是通过 CopyOnWriteArrayList
实现的。而CopyOnWriteArrayList
本质是个动态数组,所以 CopyOnWriteArraySet
相当于通过通过动态数组实现的“集合”!
CopyOnWriteArrayList
中允许有重复的元素;但是 CopyOnWriteArraySet
是一个集合,所以它不能有重复元素。因此,CopyOnWriteArrayList
额外提供了 addIfAbsent()
和 addAllAbsent()
这两个添加元素的 API
,通过这些 API
来添加元素时,只有当元素不存在时才执行添加操作!
CopyOnWriteArraySet
的“线程安全”机制,和 CopyOnWriteArrayList
一样,是通过 volatile
和 ReentrantLock
(独占锁) 来实现的
CopyOnWriteArraySet
源码
CopyOnWriteArraySet
的构造器
public class CopyOnWriteArraySet<E> extends AbstractSet<E>
implements java.io.Serializable {
private final CopyOnWriteArrayList<E> al;
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
public CopyOnWriteArraySet(Collection<? extends E> c) {
if (c.getClass() == CopyOnWriteArraySet.class) {
@SuppressWarnings("unchecked") CopyOnWriteArraySet<E> cc =
(CopyOnWriteArraySet<E>)c;
al = new CopyOnWriteArrayList<E>(cc.al);
}else {
al = new CopyOnWriteArrayList<E>();
al.addAllAbsent(c);
}
}
}
CopyOnWriteArraySet
的添加元素(独占锁 ReentrantLock
)
public boolean add(E e) {
return al.addIfAbsent(e);
}
public boolean addIfAbsent(E e) {
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) {
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
CopyOnWriteArraySet
的移除元素(独占锁 ReentrantLock
)
public boolean remove(Object o) {
return al.remove(o);
}
public boolean remove(Object o) {
Object[] snapshot = getArray();
int index = indexOf(o, snapshot, 0, snapshot.length);
return (index < 0) ? false : remove(o, snapshot, index);
}
private boolean remove(Object o, Object[] snapshot, int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) findIndex: {
int prefix = Math.min(index, len);
for (int i = 0; i < prefix; i++) {
if (current[i] != snapshot[i] && eq(o, current[i])) {
index = i;
break findIndex;
}
}
if (index >= len)
return false;
if (current[index] == o)
break findIndex;
index = indexOf(o, current, index, len);
if (index < 0)
return false;
}
Object[] newElements = new Object[len - 1];
System.arraycopy(current, 0, newElements, 0, index);
System.arraycopy(current, index + 1,
newElements, index,
len - index - 1);
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
CopyOnWriteArraySet
的获取元素
public Iterator<E> iterator() {
return al.iterator();
}
public Iterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}