CopyOnWriteArrayList源码分析

CopyOnWriteArrayList 是 Java 并发包中的一个线程安全的 List 实现类,它通过在修改操作(add、set、remove 等)时对底层数组进行复制来实现线程安全,从而避免了使用显式的同步操作。以下是对 CopyOnWriteArrayList 的简要源码分析:

1. 主要成员变量

CopyOnWriteArrayList 的源码中,有几个主要的成员变量:

private transient volatile Object[] array;
  • array: 内部使用的数组,用于存储元素。

2. 构造函数

CopyOnWriteArrayList 提供了多个构造函数,其中包括:

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);
}
  • setArray(Object[] a): 设置内部使用的数组。

3. 添加元素:add方法

CopyOnWriteArrayListadd 方法用于向列表末尾添加元素:

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();
    }
}
  • getArray(): 获取当前的数组。
  • Arrays.copyOf(): 复制数组并添加新元素。
  • setArray(Object[] a): 设置新的数组。

4. 获取元素:get方法

CopyOnWriteArrayListget 方法用于获取指定位置的元素:

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

@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
    return (E) a[index];
}
  • get(Object[] a, int index): 从给定数组中获取指定索引位置的元素。

5. 删除元素:remove方法

CopyOnWriteArrayListremove 方法用于删除指定位置的元素:

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)
            setArray(Arrays.copyOf(elements, len - 1));
        else {
            Object[] newElements = new Object[len - 1];
            System.arraycopy(elements, 0, newElements, 0, index);
            System.arraycopy(elements, index + 1, newElements, index, numMoved);
            setArray(newElements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }
}
  • System.arraycopy(): 使用 System 类的 arraycopy 方法来移动元素。
  • setArray(Object[] a): 设置新的数组。

6. 总结

CopyOnWriteArrayList 的源码分析帮助我们理解了它是如何通过在修改操作时复制数组来实现线程安全的。每次修改操作都会复制一份新的数组,这样可以确保读操作不受修改操作的影响,从而实现了读写分离的效果。这种实现方式适用于读多写少的场景,但是需要注意复制操作可能会带来额外的开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT洋少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值