首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【集合-CopyOnWriteArrayList 源码解析】

【集合-CopyOnWriteArrayList 源码解析】

作者头像
贺公子之数据科学与艺术
发布2025-08-29 17:55:07
发布2025-08-29 17:55:07
15000
代码可运行
举报
运行总次数:0
代码可运行

CopyOnWriteArrayList是Java中线程安全的集合类之一,本文将对CopyOnWriteArrayList的源码进行解析,以帮助理解其原理和使用方式。

CopyOnWriteArrayList是通过读写分离的思想实现线程安全的,即在读操作和写操作时使用不同的数据副本。读操作不会阻塞,而写操作则会创建一个新的数据副本,以保证线程安全。

CopyOnWriteArrayList的内部维护了一个数组,用来存储集合元素。当有写操作时,会创建一个新的数组来执行写操作,并将原数组的内容复制到新数组中。这样就保证了读操作不会受到写操作的影响。

首先,我们来看CopyOnWriteArrayList的构造方法:

代码语言:javascript
代码运行次数:0
运行
复制
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中的元素复制到新数组
    }
    setArray(elements);
}

copyOnWriteArrayList有两个构造方法,一个是无参构造方法,一个是接受一个集合参数的构造方法。无参构造方法会创建一个空数组,而接受集合参数的构造方法会将集合中的元素复制到新数组中。

接下来,我们看下CopyOnWriteArrayList的主要方法。

  1. add方法:
代码语言:javascript
代码运行次数:0
运行
复制
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();
    }
}

add方法会先获取当前数组,然后将数组长度加1,并创建一个新的数组,将原数组的内容复制到新数组中,再将新元素添加到新数组的最后。最后将新数组设置为当前数组。

  1. get方法:
代码语言:javascript
代码运行次数:0
运行
复制
public E get(int index) {
    return get(getArray(), index);
}

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

get方法会直接从当前数组中获取指定位置的元素。

  1. set方法:
代码语言:javascript
代码运行次数:0
运行
复制
public E set(int index, E element) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        E oldValue = get(elements, index);
        if (oldValue != element) {
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len);
            newElements[index] = element;
            setArray(newElements);
        } else {
            setArray(elements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }
}

set方法也会先获取当前数组,然后将数组中指定位置的元素替换为新元素,并创建一个新数组来保存修改后的内容。

通过以上代码分析,我们可以看出CopyOnWriteArrayList的核心原理是“写时复制”。每次写操作都会创建一个新的数组来执行操作,并将新数组设置为当前数组,从而保证了读操作的线程安全性。

需要注意的是,由于每次写操作都会创建一个新的数组,所以CopyOnWriteArrayList的写操作的性能较低,适用于读操作较多、写操作较少的场景。

总结: CopyOnWriteArrayList通过读写分离的思想实现了线程安全的集合类。其核心原理是“写时复制”,即每次写操作都会创建一个新的数组来执行操作,并将新数组设置为当前数组,以保证线程安全。由于写操作会创建新数组,所以写操作的性能较低,适用于读操作较多、写操作较少的场景。以上就是CopyOnWriteArrayList源码的基本解析。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档