返回

专项解读:CopyOnWriteArrayList底层机制

后端

CopyOnWriteArrayList简介

CopyOnWriteArrayList是Java集合框架中的一种特殊的并发容器,它在读写分离的基础上实现了线程安全,读写操作不会互相阻塞,适用于读多写少的应用场景。

CopyOnWriteArrayList的底层原理是:每次修改操作都会创建一个新的内部数组,并将原数组的所有元素拷贝到新数组中,然后再对新数组进行修改。这样一来,读操作始终从原数组中获取数据,而写操作则在新的数组中进行,从而避免了读写冲突。

CopyOnWriteArrayList的底层原理

为了更深入地理解CopyOnWriteArrayList的底层原理,我们来看看它的源码。

public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {

    private transient volatile Object[] array;

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

    public CopyOnWriteArrayList(Collection<? extends E> c) {
        Object[] elements;
        if (c.getClass() == CopyOnWriteArrayList.class) {
            elements = ((CopyOnWriteArrayList<?>) c).getArray();
        } else {
            elements = c.toArray();
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elements.getClass() != Object[].class)
                elements = Arrays.copyOf(elements, elements.length, Object[].class);
        }
        setArray(elements);
    }

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

    public boolean add(E e) {
        synchronized (this) {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        }
    }

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

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

从源码中可以看出,CopyOnWriteArrayList的底层是一个volatile修饰的数组array,它存储了所有的元素。

当调用get方法获取元素时,直接从array中获取,不会进行任何同步操作,因此get操作是线程安全的。

当调用add方法添加元素时,首先获取当前的array,然后创建一个新的数组,并将原数组的所有元素拷贝到新数组中,然后再将要添加的元素添加到新数组中,最后将array指向新数组。

由于add操作需要创建一个新的数组,因此是线程不安全的,需要进行同步操作。

CopyOnWriteArrayList的适用场景

CopyOnWriteArrayList适用于读多写少的应用场景,因为它的读操作是线程安全的,而写操作需要进行同步,因此如果写操作比较频繁,则会影响性能。

常见的适用场景包括:

  • 线程池管理:线程池中维护着一个线程队列,当有任务提交时,会将任务添加到队列中,当线程池中空闲线程获取任务时,会从队列中获取一个任务并执行。
  • 消息队列:消息队列中维护着一个消息队列,生产者线程将消息添加到队列中,消费者线程从队列中获取消息并处理。
  • 并发缓存:并发缓存中维护着一个缓存,当有数据需要缓存时,会将数据添加到缓存中,当需要获取数据时,会从缓存中获取数据。

总结

CopyOnWriteArrayList是一种线程安全的并发容器,它在读写分离的基础上实现了线程安全,读写操作不会互相阻塞,适用于读多写少的应用场景。通过分析CopyOnWriteArrayList的源码,我们可以深入理解其底层工作原理和适用场景。