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.