java,CopyOnWriteArrayList解读

168 阅读1分钟

添加操作

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

final void setArray(Object[] a) {
    array = a;
}

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

加锁,否则会copy出很多副本

读取数据

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

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

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

读的时候不用加锁,读到的为原来的数据(可重复读:一个事务在执行过程中,看到的数据和事务启动时一致)

使用场景

  1. 读多写少

缺点

  1. 数据无法保证实时一致性
  2. 由于写时复制,可能存在多个对象,会引起频繁的young gc 和 full gc

其他

虽然java只提供了List和Set的版本,但是其实大体上都是一样的,写-复制-更新。(避免锁)