Java CopyOnWriteArrayList是如何用副本替换原始数组的?何时发生?
根据CopyOnWriteArrayList JavaDoc: java.util.ArrayList的线程安全变体,其中所有 通过创建新的 基础数组的副本 每个线程总是在变异后处理自己的本地副本吗Java CopyOnWriteArrayList是如何用副本替换原始数组的?何时发生?,java,Java,根据CopyOnWriteArrayList JavaDoc: java.util.ArrayList的线程安全变体,其中所有 通过创建新的 基础数组的副本 每个线程总是在变异后处理自己的本地副本吗 我认为副本应该替换原始阵列。如何用原始数组替换副本以供其他线程使用,以及在什么阶段会发生这种情况?如果您查看集合实现,它将使用现有元素创建新对象数组,并在操作后替换新数组 /** * Replaces the element at the specified position in this li
我认为副本应该替换原始阵列。如何用原始数组替换副本以供其他线程使用,以及在什么阶段会发生这种情况?如果您查看集合实现,它将使用现有元素创建新对象数组,并在操作后替换新数组
/**
* Replaces the element at the specified position in this list with the
* specified element.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
synchronized (lock) {
Object[] elements = getArray();//creating the new array with ting vaue
E oldValue = elementAt(elements, index);
if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);//replacing the old array
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
}
}
以相同的方式实现add和remove方法
因为所有这些方法都是线程安全的,所以假设两个线程都使用add方法,那么两个线程都有自己的元素副本
从文件:
快照样式迭代器方法使用对创建迭代器时数组状态的引用。该数组在迭代器的生命周期内不会更改,因此不可能发生干扰,并且迭代器保证不会抛出ConcurrentModificationException。自创建迭代器以来,迭代器不会反映对列表的添加、删除或更改
它不会合并回主阵列。数据结构中有一个指向数组的指针,该数组被更改为指向新数组。您已经有了源代码。为什么不看看它,看看它是如何工作的呢?是的@Andreas,我在发布后和发布前都看到了源代码。但是,还不完全清楚。add方法在操作前已锁定,在add操作完成后已解锁。要确认为什么add处理的是副本而不是主阵列。我认为原因是迭代器在主数组上工作,如果没有在副本上完成add,那么它可能抛出CME。请建议我的理解是否正确?你是正确的。在副本(包括新值)完成之前,您无法使其对其他线程可见。-请注意,您的问题措辞错误。没有进行合并,也没有主数组。一旦复制和更新操作完成,更新的副本将替换原始数组,此时所有其他线程都将看到它。@Andreas,我已经更新了问题