Collection集合04-CopyOnWriteArrayList

UML图

构造函数

  • 默认是volatile修饰的Object数组;

  • 默认是长度为0

public CopyOnWriteArrayList() {
        setArray(new Object[0]);
    }

private transient volatile Object[] array;

数据的存储和获取

1.add方法

  • 扩容增加1个元素

  • 将新的元素加到最后

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();//关锁
        }
}

final Object[] getArray() {
        return array;
    }

2.get方法

public E get(int index) {
        return get(getArray(), index);
    }

 private E get(Object[] a, int index) {
        return (E) a[index];
    }

数据移除

  • 移除index元素

  • 将其他元素拷贝到新的数组,赋值成员变量

public E remove(int index) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            E oldValue = get(elements, index);
            int numMoved = len - index - 1;
            if (numMoved == 0)//如果长度只剩余1时
                setArray(Arrays.copyOf(elements, len - 1)); //
            else {
                Object[] newElements = new Object[len - 1];
                System.arraycopy(elements, 0, newElements, 0, index);//拷贝index前部分数据
                System.arraycopy(elements, index + 1, newElements, index,numMoved);//拷贝index+1之后,
                setArray(newElements);
            }
            return oldValue;
        } finally {
            lock.unlock();
        }
    }

数据清空

  • 赋值一个新的长度为0 的Object数组
 public void clear() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            setArray(new Object[0]);
        } finally {
            lock.unlock();
        }
    }

总结

    看了几个常用的方法,进行总结:

  • 初始化长度为0;

  • 每新增一个元素就将生成一个长度+1的数组,将原数组赋值给新数组;

  • 删除元素将删除的元素,之前的元素去键,和之后的元素区间进行拷贝。生成新的数组,将新数组进行赋值给类成员数组

优点:

  • 线程安全,通过不公平锁进行线程加锁

  • 有数组的所有优点,查找迅速。

缺点:

  • 性能差

    • 独占式锁操作比较耗时

    • 频繁的对象创建,每增加一个元素或者删除一个元素都要新增一个对象数组

posted @ 2020-08-11 23:26  PerfectLi  阅读(137)  评论(0编辑  收藏  举报