当前位置: 首页 > 科技观察

面试官:你听说过CopyOnWrite容器吗?

时间:2023-03-20 00:11:07 科技观察

CopyOnWrite容器本节主要介绍CopyOnWrite容器。其实就是程序设计中的一种优化策略,从字面意思来说就是copy-on-write的思想。你是什??么意思?即当计算机执行并发调用时,比如需要修改某个数据,它不会直接修改原始数据,而是复制原始数据进行修改。再理解CopyOnWrite容器就很容易了,意思是一样的。复制当前容器中的数据,即复制容器,对其进行修改,达到读写分离的目的。最后,原始容器的引用用于执行新容器。.这种设计的好处是显而易见的。读操作不需要频繁加锁。JAVA还为我们提供了比较有用的类opyOnWriteArrayList和CopyOnWriteArraySet。本节主要讲解opyOnWriteArrayList。CopyOnWriteArrayList的优缺点CopyOnWriteArrayList常用于读多写少的场景。因为不需要锁等同步方案,所以在读场景下性能更佳。但是它也有缺点,因为它的实现需要复制一份数据,所以如果数据量特别大,内存压力会比较大,容易触发FULLGC。另外,因为读写都是在新的容器上进行的,所以在写操作的时候不会阻塞读,有时会读到旧的数据。如何使用?publicclassCopyOnWriteArrayListimplementsList,RandomAccess,Cloneable,java.io.Serializable{...}它实现了List接口,所以在使用上类似。publicstaticvoidmain(String[]args){CopyOnWriteArrayListlist=newCopyOnWriteArrayList<>();列表.添加(1);System.out.println(list.get(0));}很简单,不多说了,下面重点说说它的实现。源码分析,我们先看它的构造函数。//默认情况下publicCopyOnWriteArrayList(){setArray(newObject[0]);}//允许指定集合publicCopyOnWriteArrayList(Collectionc){Object[]elements;如果(c.getClass()==CopyOnWriteArrayList.class)元素=((CopyOnWriteArrayList)c).getArray();else{元素=c.toArray();如果(c.getClass()!=java.util.ArrayList.class)elements=Arrays.copyOf(elements,elements.length,Object[].class);}setArray(元素);}//包含给定的复制元素publicCopyOnWriteArrayList(E[]toCopyIn){setArray(Arrays.copyOf(toCopyIn,toCopyIn.length,Object[].class));让我们看看add()方法。publicbooleanadd(Ee){//获取锁finalReentrantLocklock=this.lock;锁.锁();try{//获取数组Object[]elements=getArray();intlen=elements.length;//复制对象[]newElements=Arrays.copyOf(elements,len+1);//向复制容器添加新元素newElements[len]=e;//参照原容器执行新容器setArray(newElements);返回真;}最后{lock.unlock();}}finalvoidsetArray(Object[]a){array=a;}我们可以看到在写的过程中,需要加锁,再看get()方法。publicEget(intindex){returnget(getArray(),index);}privateEget(Object[]a,intindex){return(E)a[index];}可以看出这个过程确实没有加Lock,所以从源码来看,CopyOnWriteArrayList适合读多写少的场景。结束语有兴趣的同学可以继续研究它的源码,比较容易。大家也可以举一反三,尝试通过CopyOnWrite机制写一个CopyOnWriteMap。可以参考CopyOnWriteArrayList的实现。