1.原理CopyOnWriteArrayList有点像线程安全的ArrayList。其实它的原理简单概括就是读写分离。写操作是对复制的数组进行的,读操作是对原数组进行的,读写分离。Write操作被锁定。写操作完成后,原数组指向新数组。下面简单看一下add和get方法是如何实现写和读操作的。/***将指定的元素附加到此列表的末尾。**@parame元素要附加到这个列表*@return{@codetrue}(由{@linkCollection#add}指定)*/publicbooleanadd(Ee){finalReentrantLocklock=this.lock;锁.锁();尝试{对象[]元素=getArray();intlen=elements.length;对象[]newElements=Arrays.copyOf(元素,len+1);新元素[len]=e;设置数组(新元素);返回真;}最后{lock.unlock();}}@SuppressWarnings("unchecked")privateEget(Object[]a,intindex){return(E)a[index];}/***{@inheritDoc}**@throwsIndexOutOfBoundsException{@inheritDoc}*/publicEget(intindex){returnget(getArray(),index);}2.适用场景因为每次写入数据都会开辟一个新的数组,会消耗内存,并且而且加锁了,写的性能不是很好。读取操作非常快,还支持边读边写。所以非常适合阅读多写少的场景。3.缺点:内存消耗大:每次写操作都需要拷贝一个新的数组,所以内存占用非常大,数据不一致:读取数据时,可能读取不到最新的数据,因为写入的部分数据可能不同步到读取数组。不适合对内存敏感,实时性要求高的场景。4、CopyOnWriteArraySet在浏览CopyOnWriteArrayList源码的过程中,无意中发现CopyOnWriteArraySet内部其实是用一个CopyOnWriteArrayList来实现的。公共类CopyOnWriteArraySetextendsAbstractSetimplementsjava.io.Serializable{privatefinalCopyOnWriteArrayListal;/***如果指定的元素不存在,则将其添加到此集合中。*更正式地说,将指定的元素{@codee}添加到此集合,如果*该集合不包含元素{@codee2}这样*(e==null?e2==null:e.equals(e2))。*如果此集合已包含该元素,则调用保持集合不变*并返回{@codefalse}。**@parame元素被添加到这个集合*@return{@codetrue}如果这个集合没有已经包含指定的*元素*/publicbooleanadd(Ee){returnal.addIfAbsent(e);}}和CopyOnWriteArrayList的addIfAbsent方法其实和add方法的内部实现类似(都是新复制的数组,加锁),只是多判断/***追加元素,如果不存在。**@parame要添加到此列表的元素,如果不存在*@return{@codetrue}如果添加了元素*/publicbooleanaddIfAbsent(Ee){Object[]snapshot=getArray();返回indexOf(e,snapshot,0,snapshot.length)>=0?false:addIfAbsent(e,snapshot);}/***使用强提示的addIfAbsent版本*最近的快照不包含e。*/privatebooleanaddIfAbsent(Ee,Object[]snapshot){finalReentrantLocklock=this.lock;锁.锁();尝试{对象[]current=getArray();intlen=current.length;if(snapshot!=current){//优化失败的竞争到另一个addXXX操作intcommon=Math.min(snapshot.length,len);对于(inti=0;i=0)返回false;}Object[]newElements=Arrays.copyOf(current,len+1);新元素[len]=e;设置数组(新元素);返回真;}最后{锁。开锁();}}5.扩展:CopyOnWriteHashMapJava没有提供类似CopyOnWriteHashMap的类,可能它已经有了ConcurrentHashMap。理解了CopyOnWriteArrayList的思想之后,我们其实可以写一个简单的CopyOnWriteHashMapimportjava.util.Collection;importjava.util.Map;importjava.util.Set;publicclassCopyOnWriteHashMapimplementsMap,Cloneable{privatevolatileMapinternalMap;publicCopyOnWriteHashMap(){internalMap=newHashMap();}publicVput(Kkey,Vvalue){synchronized(this){MapnewMap=newHashMap(internalMap);Vval=newMap.put(key,value);内部地图=新地图;返回值;}}publicVget(Objectkey){returninternalMap.get(key);}}6.为什么CopyOnWriteArrayList比Vector好?在Vector内部,增删改查都是同步的,每个方法都需要解锁,会大大降低性能。锁定,所以CopyOnWriteArrayList在读取方面明显优于Vector。所以CopyOnWriteArrayList最好用在读多写少的场景。