0%

CopyOnWrite容器

CopyOnWrite容器

什么是CopyOnWrite容器呢?CopyOnWrite容器是一个写时复制的容器。就是在向容器中添加元素时,不会直接向当前容器中添加,而是将当前容器进行copy,复制出一个新的容器,然后往新的容器中添加元素,添加完元素之后,再将容器的引用指向新的容器。使得我们可以对CopyOnWrite容器进行并发的读而不需要加锁,采用了读写分离的思想。

使用的场景是读多写少的时候使用

以CopyOnWriteArrayList为例

CopyOnWriteArrayList

CopyOnWriteArrayList是同步List的并发替代品,可以提供更好的并发性,并且避免了在迭代期间对容器加锁和复制,在每次修改的时,会创建一个新的容器拷贝,以此来实现可变性

1
private transient volatile Object[] array;

实际是对底层数组的复制操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 {// 值没有修改
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}

每次容器改变对于基础数组的复制也是有一定开销的,特别是当容器较大时,所以该种方式比较适合于读取操作的次数远大于修改操作的次数时才适用