CopyOnWriteArraySet 也是JDK 为我们提供的 CopyOnWrite 容器的实现。CopyOnWriteArraySet 是基于CopyOnWriteArrayList 实现的,我们来看下他的源代码是如何实现的:
private final CopyOnWriteArrayList<E> al;
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
public boolean add(E e) {
return al.addIfAbsent(e);
}
当我们 通过 CopyOnWriteArraySet 构造方法创建 一CopyOnWriteArraySet 对象的时候,其实创建了一个CopyOnWriteArrayList 对象,当我们 调用add(E e) 方法的时候其实是调用了 CopyOnWriteArrayList 的addIfAbsent(E e) 方法:
public boolean addIfAbsent(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
// Copy while checking if already present.
// This wins in the most common case where it is not present
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = new Object[len + 1];
for (int i = 0; i < len; ++i) {
if (eq(e, elements[i]))
return false; // exit, throwing away copy
else
newElements[i] = elements[i];
}
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
CopyOnWriteArrayList的addIfAbsent方法.adIfAbsent方法同样采用锁保护,并创建一个新的大小+1的Object数组。遍历当前Object数组,如Object数组中已有了当前元素,则直接返回,如果没有则放入Object数组的尾部,并返回。
由此可见CopyOnWriteArraySet在add时每次都要进行数组的遍历,因此其性能会低于CopyOnWriteArrayList.