publicclassCopyOnWriteArraySet<E>extendsAbstractSet<E>implementsjava.io.Serializable{privatefinalCopyOnWriteArrayList<E> al;// 无参构造器publicCopyOnWriteArraySet(){// 创建了一个 CopyOnWriteArrayList 对象
al =newCopyOnWriteArrayList<E>();}// 有参构造器publicCopyOnWriteArraySet(Collection<?extendsE> c){if(c.getClass()==CopyOnWriteArraySet.class){@SuppressWarnings("unchecked")CopyOnWriteArraySet<E> cc =(CopyOnWriteArraySet<E>)c;
al =newCopyOnWriteArrayList<E>(cc.al);}else{
al =newCopyOnWriteArrayList<E>();
al.addAllAbsent(c);}}}
CopyOnWriteArraySet 的添加元素(独占锁 ReentrantLock)
publicbooleanadd(E e){// 调用CopyOnWriteArrayList的当不存在时添加方法return al.addIfAbsent(e);}// 不存在才会添加publicbooleanaddIfAbsent(E e){Object[] snapshot =getArray();returnindexOf(e, snapshot,0, snapshot.length)>=0?false:addIfAbsent(e, snapshot);}privatebooleanaddIfAbsent(E e,Object[] snapshot){// 使用独占锁finalReentrantLock lock =this.lock;
lock.lock();// 加锁try{Object[] current =getArray();int len = current.length;if(snapshot != current){// 说明在这之前已经被修改过了int common =Math.min(snapshot.length, len);// 判断元素是否存在于当前数组中,如果存在直接返回false;// 这里巧妙地思路:判断两个数组相等 1长度相等 2数组每一位相等 不需要进行双重循环for(int i =0; i < common; i++)if(current[i]!= snapshot[i]&&eq(e, current[i]))returnfalse;if(indexOf(e, current, common, len)>=0)returnfalse;}// 添加并修改Object[] newElements =Arrays.copyOf(current, len +1);
newElements[len]= e;setArray(newElements);returntrue;}finally{
lock.unlock();// 解锁}}
CopyOnWriteArraySet 的移除元素(独占锁 ReentrantLock)
publicbooleanremove(Object o){// 调用CopyOnWriteArrayList的 remove()return al.remove(o);}publicbooleanremove(Object o){Object[] snapshot =getArray();int index =indexOf(o, snapshot,0, snapshot.length);return(index <0)?false:remove(o, snapshot, index);}privatebooleanremove(Object o,Object[] snapshot,int index){// 使用独占锁finalReentrantLock 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)returnfalse;if(current[index]== o)break findIndex;
index =indexOf(o, current, index, len);if(index <0)returnfalse;}Object[] newElements =newObject[len -1];System.arraycopy(current,0, newElements,0, index);System.arraycopy(current, index +1,
newElements, index,
len - index -1);setArray(newElements);returntrue;}finally{
lock.unlock();}}