首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CopyOnWriteArrayList的行为

CopyOnWriteArrayList的行为
EN

Stack Overflow用户
提问于 2010-11-19 17:43:46
回答 2查看 8.1K关注 0票数 17

CopyOnWriteArrayList的Javadocs说

:ArrayList的一个线程安全变体,在该变体中,所有的可变操作(添加、设置等)都是通过创建基础数组的新副本来实现的。

我现在很困惑,其他线程什么时候会看到这个新副本中出现的变化?这是否意味着基础数组的拷贝数将等于集合的突变数?如果不是,何时将这些单独副本的更改转移到基础数组,以便其他线程能够看到它们?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-19 17:54:26

这里的想法是,每当您向CopyOnWriteArrayList添加或删除时,基础数组基本上都是通过修改复制的。

是否意味着基础数组的拷贝数等于集合的突变数。

是的,对于每个更新ArrayList的线程,所有其他包含旧副本的线程本质上都将引用不同的数组。

何时将这些单独副本的更改传输到基础数组,以便其他线程能够看到它们?

当前正在查看的数组(假设您的迭代器)永远不会改变。当您从数组读取时,您正在读取它,就像开始读取时一样。如果CopyOnWriteArrayList由另一个线程更改,则不会影响当前正在观察的数组。

要获得最新版本,请执行类似于list.iterator();的新读取

尽管如此,更新这个集合会破坏性能。如果您尝试对一个CopyOnWriteArrayList排序,您将看到列表抛出一个UsupportedOperationException (排序调用集合上的设置N次)。只有在向上读取90+%时,才应该使用此读取。

票数 20
EN

Stack Overflow用户

发布于 2018-07-13 08:40:51

写数组列表的复制实现使用基础数组,并使用setter和getter方法访问它。

代码语言:javascript
复制
/** The array, accessed only via getArray/setArray. */
private transient volatile Object[] array;

/**
 * Gets the array.  Non-private so as to also be accessible
 * from CopyOnWriteArraySet class.
 */
final Object[] getArray() {
    return array;
}

/**
 * Sets the array.
 */
final void setArray(Object[] a) {
    array = a;
}

因此,对于add,设置操作,它创建当前数组的副本(使用getArray),并添加元素并返回更新的数组(使用setArray)。

代码语言:javascript
复制
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();
    }
}

是的,在添加或设置方法之前访问arrayList的线程将有一个陈旧的数据副本(如果您可以处理某种程度的陈旧数据,因为CopyOnWriteArrayList的设计思想是遍历操作将超过添加或更新操作),所有将创建迭代器或使用get操作的线程都将拥有arraylist的最新数据。

代码语言:javascript
复制
public E get(int index) {
    return get(getArray(), index);
}

public Iterator<E> iterator() {
    return new COWIterator<E>(getArray(), 0);
}

在这里,getarray将给出arrayList的最新状态。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4227827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档