`CopyOnWriteArrayList` 是一个线程安全的列表,它继承自 `AbstractList` 类,实现了 `List` 接口,并且还实现了 `RandomAccess`、`Cloneable` 和 `Serializable` 接口。它的主要特点是在进行写操作时,会创建一个新的数组副本,以保证读操作的线程安全性,从而避免了读写冲突。
首先解析`CopyOnWriteArrayList`的内部类:
内部类`COWIterator`
`CopyOnWriteArrayList`的内部类`COWIterator`,它实现了`ListIterator`接口,用于在`CopyOnWriteArrayList`上进行安全的迭代。
static final class COWIterator<E> implements ListIterator<E> {
private final Object[] snapshot; // 用于保存迭代过程中的快照数组
private int cursor; // 迭代器当前的游标位置
private COWIterator(Object[] elements, int initialCursor) {
cursor = initialCursor; // 初始化游标位置
snapshot = elements; // 获取传入的数组快照
}
接下来是`ListIterator`接口的方法的实现,以支持安全的迭代操作。因为`CopyOnWriteArrayList`是线程安全的,所以该迭代器可以在并发修改的情况下安全地遍历列表。
public boolean hasNext() {
return cursor < snapshot.length; // 判断是否还有下一个元素
}
public boolean hasPrevious() {
return cursor > 0; // 判断是否还有前一个元素
}
@SuppressWarnings("unchecked")
public E next() {
if (!hasNext())
throw new NoSuchElementException();
return (E) snapshot[cursor++]; // 返回下一个元素并将游标位置后移
}
@SuppressWarnings("unchecked")
public E previous() {
if (!hasPrevious())
throw new NoSuchElementException();
return (E) snapshot[--cursor]; // 返回前一个元素并将游标位置前移
}
public int nextIndex() {
return cursor; // 返回下一个元素的索引
}
public int previousIndex() {
return cursor - 1; // 返回前一个元素的索引
}
`remove()`、`set(E e)` 和 `add(E e)` 方法在迭代过程中不支持修改操作,因为`CopyOnWriteArrayList`的迭代器是只读的。
public void remove() {
throw new UnsupportedOperationException(); // 不支持删除操作
}
public void set(E e) {
throw new UnsupportedOperationException(); // 不支持修改操作
}
public void add(E e) {
throw new UnsupportedOperationException(); // 不支持添加操作
}
`forEachRemaining(Consumer<? super E> action)` 方法用于在迭代器当前位置之后遍历所有剩余的元素,并对它们执行指定的操作。
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
Object[] elements = snapshot;
final int size = elements.length;
for (int i = cursor; i < size; i++) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
action.accept(e); // 对剩余的每个元素执行指定的操作
}
cursor = size; // 将游标位置设置为数组长度,表示已经遍历完成
}
总结:`COWIterator`是`CopyOnWriteArrayList`的内部类,它实现了`ListIterator`接口,用于在`CopyOnWriteArrayList`上进行安全的迭代操作。迭代器基于原始列表的快照数组进行遍历,因此不受并发修改的影响,并且不支持对列表的修改操作。这样,`CopyOnWriteArrayList`可以在并发读取的情况下保持数据的一致性和稳定性。
`CopyOnWriteArrayList`的内部类`COWSubList`
`CopyOnWriteArrayList`的内部类`COWSubList`,它实现了`AbstractList`接口,并且支持`RandomAccess`随机访问特性。`COWSubList`表示`CopyOnWriteArrayList`的子列表,用于实现对原始列表的部分元素进行操作。
让我们逐行解析这段代码(中文解释在注释中):
private static class COWSubList<E>
extends AbstractList<E>
implements RandomAccess
{
private final CopyOnWriteArrayList<E> l; // 引用原始的CopyOnWriteArrayList
private final int offset; // 子列表在原始列表中的偏移量
private int size; // 子列表的大小
private Object[] expectedArray; // 用于记录原始列表的数组,用于检测并发修改
COWSubList(CopyOnWriteArrayList<E> list, int fromIndex, int toIndex) {
l = list; // 初始化引用
expectedArray = l.getArray(); // 获取原始列表的数组快照
offset = fromIndex; // 设置子列表的起始偏移量
size = toIndex - fromIndex; // 计算子列表的大小
}
接下来是一系列辅助方法用于处理并发修改检测以及边界检查。这些方法都是在执行修改操作之前进行检查的。
private void checkForComodification() {
if (l.getArray() != expectedArray)
throw new ConcurrentModificationException();
}
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
接下来是一些基本的List操作的实现,如`set`、`get`、`add`、`remove`等,它们都是通过获取`ReentrantLock`来实现线程安全。
public E set(int index, E element) {
// 获取ReentrantLock,确保线程安全
final ReentrantLock lock = l.lock;
lock.lock();
try {
rangeCheck(index); // 边界检查
checkForComodification(); // 并发修改检测
E x = l.set(index + offset, element); // 调用原始列表的set方法
expectedArray = l.getArray(); // 更新数组快照
return x;
} finally {
lock.unlock(); // 释放锁
}
}
public E get(int index) {
// 获取ReentrantLock,确保线程安全
final ReentrantLock lock = l.lock;
lock.lock();
try {
rangeCheck(index); // 边界检查
checkForComodification(); // 并发修改检测
return l.get(index + offset); // 调用原始列表的get方法
} finally {
lock.unlock(); // 释放锁
}
}
// 其他方法类似,都是通过获取锁来确保线程安全并调用原始列表的相应方法
// 包括 size、add、clear、remove、iterator、listIterator 等方法的实现
最后还有一些额外的操作,如`forEach`、`replaceAll`、`sort`、`removeAll`、`retainAll`、`removeIf`等。
public void forEach(Consumer<? super E> action) {
// ... 省略实现,类似地获取锁,检测并发修改,然后进行相应操作 ...
}
public void replaceAll(UnaryOperator<E> operator) {
// ... 省略实现,类似地获取锁,检测并发修改,然后进行相应操作 ...
}
public void sort(Comparator<? super E> c) {
// ... 省略实现,类似地获取锁,检测并发修改,然后进行相应操作 ...
}
public boolean removeAll(Collection<?> c) {
// ... 省略实现,类似地获取锁,检测并发修改,然后进行相应操作 ...
}
public boolean retainAll(Collection<?> c) {
// ... 省略实现,类似地获取锁,检测并发修改,然后进行相应操作 ...
}
public boolean removeIf(Predicate<? super E> filter) {
// ... 省略实现,类似地获取锁,检测并发修改,然后进行相应操作 ...
}
// 其中的 spliterator() 方法用于返回一个Spliterator,支持并行遍历
// 这些操作都是在获取锁的情况下进行,确保了线程安全
总结:`COWSubList`是`CopyOnWriteArrayList`的内部类,用于实现对原始列表的部分元素进行操作。它通过获取`ReentrantLock`实现线程安全,并使用`expectedArray`来检测并发修改。通过这种方式,`CopyOnWriteArrayList`保证了在并发修改时的安全性。
`CopyOnWriteArrayList`的另一个内部类`COWSubListIterator`
它实现了`ListIterator`接口,用于在`CopyOnWriteArrayList`的子列表上进行安全的迭代。
private static class COWSubListIterator<E> implements ListIterator<E> {
private final ListIterator<E> it; // 用于迭代原始列表的ListIterator
private final int offset; // 子列表在原始列表中的偏移量
private final int size; // 子列表的大小
COWSubListIterator(List<E> l, int index, int offset, int size) {
this.offset = offset;
this.size = size;
it = l.listIterator(index + offset); // 创建子列表的ListIterator,并设置初始位置
}
`COWSubListIterator`构造函数接收了原始列表`l`、子列表的起始索引`index`、子列表在原始列表中的偏移量`offset`,以及子列表的大小`size`。它使用`l.listIterator(index+offset)`来创建一个在子列表起始位置的`ListIterator`对象。
接下来是`ListIterator`接口的方法的实现,以支持安全的迭代操作。由于`CopyOnWriteArrayList`是线程安全的,因此该迭代器可以在并发修改的情况下安全地遍历子列表。
public boolean hasNext() {
return nextIndex() < size; // 判断是否还有下一个元素
}
public E next() {
if (hasNext())
return it.next(); // 返回下一个元素
else
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return previousIndex() >= 0; // 判断是否还有前一个元素
}
public E previous() {
if (hasPrevious())
return it.previous(); // 返回前一个元素
else
throw new NoSuchElementException();
}
public int nextIndex() {
return it.nextIndex() - offset; // 返回下一个元素的索引,考虑偏移量
}
public int previousIndex() {
return it.previousIndex() - offset; // 返回前一个元素的索引,考虑偏移量
}
`remove()`、`set(E e)` 和 `add(E e)` 方法在迭代过程中不支持修改操作,因为`CopyOnWriteArrayList`的迭代器是只读的。
public void remove() {
throw new UnsupportedOperationException(); // 不支持删除操作
}
public void set(E e) {
throw new UnsupportedOperationException(); // 不支持修改操作
}
public void add(E e) {
throw new UnsupportedOperationException(); // 不支持添加操作
}
`forEachRemaining(Consumer<? super E> action)` 方法用于在迭代器当前位置之后遍历所有剩余的元素,并对它们执行指定的操作。
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
int s = size;
ListIterator<E> i = it;
while (nextIndex() < s) {
action.accept(i.next()); // 对剩余的每个元素执行指定的操作
}
}
总结:`COWSubListIterator`是`CopyOnWriteArrayList`的内部类,它实现了`ListIterator`接口,用于在`CopyOnWriteArrayList`的子列表上进行安全的迭代操作。迭代器基于原始列表的`ListIterator`,并考虑了子列表的偏移量和大小,因此在并发修改的情况下也可以安全地遍历子列表。同样地,`COWSubListIterator`也是只读的,不支持对子列表的修改操作。
CopyOnWriteArrayList类的属性和方法解析
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
private static final long serialVersionUID = 8673264195747942595L;
final transient ReentrantLock lock = new ReentrantLock(); // 写操作的互斥锁
private transient volatile Object[] array; // 保存列表元素的数组
final Object[] getArray() {
return array;
}
final void setArray(Object[] a) {
array = a;
}
- `CopyOnWriteArrayList` 使用一个 `ReentrantLock` 锁来保护写操作,确保每次写操作都是原子的,从而避免并发冲突。
- `array` 是用于保存列表元素的数组,被声明为 `transient volatile`,保证了在序列化和反序列化时的正确性。
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();
if (c.getClass() != ArrayList.class)
elements = Arrays.copyOf(elements, elements.length, Object[].class);
}
setArray(elements);
}
public CopyOnWriteArrayList(E[] toCopyIn) {
setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
}
- `CopyOnWriteArrayList` 提供了几个构造函数,可以从已有的集合或数组初始化列表。
public int size() {
return getArray().length;
}
public boolean isEmpty() {
return size() == 0;
}
- `size()` 方法返回列表中的元素数量。
- `isEmpty()` 方法检查列表是否为空。
private static boolean eq(Object o1, Object o2) {
return (o1 == null) ? o2 == null : o1.equals(o2);
}
private static int indexOf(Object o, Object[] elements, int index, int fence) {
if (o == null) {
for (int i = index; i < fence; i++)
if (elements[i] == null)
return i;
} else {
for (int i = index; i < fence; i++)
if (o.equals(elements[i]))
return i;
}
return -1;
}
private static int lastIndexOf(Object o, Object[] elements, int index) {
if (o == null) {
for (int i = index; i >= 0; i--)
if (elements[i] == null)
return i;
} else {
for (int i = index; i >= 0; i--)
if (o.equals(elements[i]))
return i;
}
return -1;
}
- `eq()` 方法用于比较两个对象是否相等,它考虑了对象为 `null` 的情况。
- `indexOf()` 方法用于查找指定元素在数组中的索引。
- `lastIndexOf()` 方法用于查找指定元素在数组中从指定索引开始往前的最后一个匹配索引。
这些是辅助方法,将在后续的操作中被使用。
public boolean contains(Object o) {
Object[] elements = getArray();
return indexOf(o, elements, 0, elements.length) >= 0;
}
public int indexOf(Object o) {
Object[] elements = getArray();
return indexOf(o, elements, 0, elements.length);
}
public int indexOf(E e, int index) {
Object[] elements = getArray();
return indexOf(e, elements, index, elements.length);
}
public int lastIndexOf(Object o) {
Object[] elements = getArray();
return lastIndexOf(o, elements, elements.length - 1);
}
public int lastIndexOf(E e, int index) {
Object[] elements = getArray();
return lastIndexOf(e, elements, index);
}
- `contains(Object o)` 方法用于判断列表中是否包含指定元素。
- `indexOf(Object o)` 方法用于查找指定元素在列表中的索引。
- `indexOf(E e, int index)` 方法用于从指定索引开始查找指定元素在列表中的索引。
- `lastIndexOf(Object o)` 方法用于查找指定元素在列表中的最后一个索引。
- `lastIndexOf(E e, int index)` 方法用于从指定索引开始查找指定元素在列表中的最后一个索引。
这些方法都是通过调用辅助方法实现的。
public Object clone() {
try {
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> clone = (CopyOnWriteArrayList<E>) super.clone();
clone.resetLock();
return clone;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
- `clone()` 方法用于创建当前列表的浅拷贝。由于 `CopyOnWriteArrayList` 是线程安全的,因此拷贝也是安全的。注意,拷贝的 `array` 是引用原始列表的,因此是浅拷贝。
public Object[] toArray() {
Object[] elements = getArray();
return Arrays.copyOf(elements, elements.length);
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T a[]) {
Object[] elements = getArray();
int len = elements.length;
if (a.length < len)
return (T[]) Arrays.copyOf(elements, len, a.getClass());
else {
System.arraycopy(elements, 0, a, 0, len);
if (a.length > len)
a[len] = null;
return a;
}
}
- `toArray()` 方法用于将列表转换为数组。
- `toArray(T a[])` 方法用于将列表转换为指定类型的数组。
@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
return (E) a[index];
}
public E get(int index) {
return get(getArray(), index);
}
- `get(int index)` 方法用于获取列表指定索引位置的元素。
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(int index, E element)` 方法用于将列表指定索引位置的元素替换为指定的元素。在这里,使用了写操作的互斥锁来确保写操作的原子性。
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(E e)` 方法用于向列表末尾添加指定元素。
public void add(int index, E element) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + len);
Object[] newElements;
int numMoved = len - index;
if (numMoved == 0)
newElements = Arrays.copyOf(elements, len + 1);
else {
newElements = new Object[len + 1];
System.arraycopy(elements, 0, newElements, 0, index);
System.arraycopy(elements, index, newElements, index + 1, numMoved);
}
newElements[index] = element;
setArray(newElements);
} finally {
lock.unlock();
}
}
- `add(int index, E element)` 方法用于在指定索引位置添加元素。
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();
}
}
- `remove(int index)` 方法用于移除列表中指定索引位置的元素。
public boolean remove(Object o) {
Object[] snapshot = getArray();
int index = indexOf(o, snapshot, 0, snapshot.length);
return (index < 0) ? false : remove(o, snapshot, index);
}
private boolean remove(Object o, Object[] snapshot, int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) findIndex: {
int prefix = Math.min(index, len);
for (int i = 0; i < prefix; i++) {
if (current[i] != snapshot[i] && eq(o, current[i])) {
index = i;
break findIndex;
}
}
if (index >= len)
return false;
if (current[index] == o)
break findIndex;
index = indexOf(o, current, index, len);
if (index < 0)
return false;
}
Object[] newElements = new Object[len - 1];
System.arraycopy(current, 0, newElements, 0, index);
System.arraycopy(current, index + 1, newElements, index, len - index - 1);
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
- `remove(Object o)` 方法用于移除列表中指定的元素。
void removeRange(int fromIndex, int toIndex) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
throw new IndexOutOfBoundsException();
int newlen = len - (toIndex - fromIndex);
int numMoved = len - toIndex;
if (numMoved == 0)
setArray(Arrays.copyOf(elements, newlen));
else {
Object[] newElements = new Object[newlen];
System.arraycopy(elements, 0, newElements, 0, fromIndex);
System.arraycopy(elements, toIndex, newElements, fromIndex, numMoved);
setArray(newElements);
}
} finally {
lock.unlock();
}
}
- `removeRange(int fromIndex, int toIndex)` 方法用于移除列表中指定范围的元素。
public boolean addIfAbsent(E e) {
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false : addIfAbsent(e,
snapshot);
}
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) {
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
- `addIfAbsent(E e)` 方法用于向列表中添加指定元素,但仅当列表中不存在该元素时。
public boolean containsAll(Collection<?> c) {
Object[] elements = getArray();
int len = elements.length;
for (Object e : c) {
if (indexOf(e, elements, 0, len) < 0)
return false;
}
return true;
}
- `containsAll(Collection<?> c)` 方法用于检查列表是否包含指定集合中的所有元素。
public boolean removeAll(Collection<?> c) {
if (c == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (len != 0) {
int newlen = 0;
Object[] temp = new Object[len];
for (int i = 0; i < len; ++i) {
Object element = elements[i];
if (!c.contains(element))
temp[newlen++] = element;
}
if (newlen != len) {
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
lock.unlock();
}
}
- `removeAll(Collection<?> c)` 方法用于移除列表中与指定集合共有的所有元素。
public boolean retainAll(Collection<?> c) {
if (c == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (len != 0) {
int newlen = 0;
Object[] temp = new Object[len];
for (int i = 0; i < len; ++i) {
Object element = elements[i];
if (c.contains(element))
temp[newlen++] = element;
}
if (newlen != len) {
setArray(Arrays.copyOf(temp, newlen));
return true;
}
}
return false;
} finally {
lock.unlock();
}
}
- `retainAll(Collection<?> c)` 方法用于保留列表中与指定集合共有的所有元素,而移除其他元素。
public int addAllAbsent(Collection<? extends E> c) {
Object[] cs = c.toArray();
if (c.getClass() != ArrayList.class) {
cs = cs.clone();
}
if (cs.length == 0)
return 0;
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
int added = 0;
for (int i = 0; i < cs.length; ++i) {
Object e = cs[i];
if (indexOf(e, elements, 0, len) < 0 &&
indexOf(e, cs, 0, added) < 0)
cs[added++] = e;
}
if (added > 0) {
Object[] newElements = Arrays.copyOf(elements, len + added);
System.arraycopy(cs, 0, newElements, len, added);
setArray(newElements);
}
return added;
} finally {
lock.unlock();
}
}
- `addAllAbsent(Collection<? extends E> c)` 方法用于向列表中添加指定集合中不存在的元素。
public void clear() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
setArray(new Object[0]);
} finally {
lock.unlock();
}
}
- `clear()` 方法用于清空列表中的所有元素。
public boolean addAll(Collection<? extends E> c) {
Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
((CopyOnWriteArrayList<?>) c).getArray() : c.toArray();
if (cs.length == 0)
return false;
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (len == 0 && (c.getClass() == CopyOnWriteArrayList.class ||
c.getClass() == ArrayList.class)) {
setArray(cs);
} else {
Object[] newElements = Arrays.copyOf(elements, len + cs.length);
System.arraycopy(cs, 0, newElements, len, cs.length);
setArray(newElements);
}
return true;
} finally {
lock.unlock();
}
}
- `addAll(Collection<? extends E> c)` 方法用于将指定集合中的所有元素添加到列表中。
public boolean addAll(int index, Collection<? extends E> c) {
Object[] cs = c.toArray();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + len);
if (cs.length == 0)
return false;
int numMoved = len - index;
Object[] newElements;
if (numMoved == 0)
newElements = Arrays.copyOf(elements, len + cs.length);
else {
newElements = new Object[len + cs.length];
System.arraycopy(elements, 0, newElements, 0, index);
System.arraycopy(elements, index, newElements, index + cs.length, numMoved);
}
System.arraycopy(cs, 0, newElements, index, cs.length);
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
- `addAll(int index, Collection<? extends E> c)` 方法用于将指定集合中的所有元素从指定索引位置开始添加到列表中。
public void forEach(Consumer<? super E> action) {
if (action == null) throw new NullPointerException();
Object[] elements = getArray();
int len = elements.length;
for (int i = 0;
i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
action.accept(e);
}
}
- `forEach(Consumer<? super E> action)` 方法用于对列表中的每个元素执行指定的操作。
public void replaceAll(UnaryOperator<E> operator) {
if (operator == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
newElements[i] = operator.apply(e);
}
setArray(newElements);
} finally {
lock.unlock();
}
}
- `replaceAll(UnaryOperator<E> operator)` 方法用于对列表中的每个元素应用指定的操作,并将结果替换原来的元素。
public boolean removeIf(Predicate<? super E> filter) {
if (filter == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
int newlen = 0;
Object[] temp = new Object[len];
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
if (!filter.test(e))
temp[newlen++] = e;
}
if (newlen != len) {
setArray(Arrays.copyOf(temp, newlen));
return true;
}
return false;
} finally {
lock.unlock();
}
}
- `removeIf(Predicate<? super E> filter)` 方法用于根据指定的条件删除列表中的元素。
public void sort(Comparator<? super E> c) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
Object[] newElements = Arrays.copyOf(elements, elements.length);
@SuppressWarnings("unchecked")
E[] es = (E[])newElements;
Arrays.sort(es, c);
setArray(newElements);
} finally {
lock.unlock();
}
}
- `sort(Comparator<? super E> c)` 方法用于对列表进行排序。
public Spliterator<E> spliterator() {
return Spliterators.spliterator
(getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public void replaceAll(UnaryOperator<E> operator) {
if (operator == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
for (int i = 0; i < len; ++i) {
@SuppressWarnings("unchecked") E e = (E) elements[i];
newElements[i] = operator.apply(e);
}
setArray(newElements);
} finally {
lock.unlock();
}
}
- `spliterator()` 方法用于创建并返回一个拥有列表中所有元素的分割迭代器。
private Object writeReplace() {
return new ArrayList<>(this);
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
Object[] elements = (Object[]) s.readFields().get("array", null);
setArray(elements);
}
- `writeReplace()` 方法用于在序列化时替换列表,以便在反序列化时恢复原始的 `ArrayList` 对象。
- `readObject(ObjectInputStream s)` 方法用于在反序列化时读取对象,并恢复原始的 `ArrayList` 对象。
这些就是 `CopyOnWriteArrayList` 类的主要方法和实现。这个类的主要特点是它的写操作是线程安全的,因为每次写操作都会创建一个新的数组副本。这种设计适合在读操作非常频繁而写操作较少的场景中使用,例如对于读多写少的并发环境。请注意,在使用 `CopyOnWriteArrayList` 时要注意内存占用问题,因为每次写操作都会创建一个新的数组副本,可能会导致内存占用较高。
线程安全的列表实现,在写多读少的场景下性能最好的是 ConcurrentLinkedDeque。
具体见后续的分析。