有序(输入和输出相同顺序),有下标,可重复,可以有多个null,线程安全,元素的访问快,删除插入等会出现元 素的移动造成性能的增高。
1.直接创建一个长度为0的数组
public CopyOnWriteArrayList() { setArray(new Object[0]); } final void setArray(Object[] a) { array = a; }
2.add方法进行lock进行加锁(线程安全),记录原有数组,和数组的长度。将原有数组进行拷贝,并把需求容量加一进行判断(用于创建新的数组时使容量扩大一个用于存储新的元素),一切完成,将元素添加到新数组中,更改老数组的引用为新数组,返回true,解锁防止阻塞
public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } }
简言之,CopyOnWriteArrayList初始创建为0长度得数组进,每次添加的时候都会创建一个比原本长度大一的数组,将原本数组进行拷贝,然后将新元素添加进去,再将原本数组的引用修改为新的数组的引用。
{每次添加就相当于扩容,并且只有操作的的方法添加啦lock锁,读方法没有。操作方法阻塞,读取方法随时读取(有新旧数组区分,会造成多线程访问数据非最新)}