“写时复制”——要写的时候复制一份副本,往副本里面写,然后引用到这个副本,在引用到这个副本之前有读操作的话,读的还是之前的老版本,读写分离,写不影响读可以并发读读,读写,但是写写的时候还是冲突的,如果拷贝了N个副本,最后到底引用谁呢,引用某个副本,写到其他副本上的数据就丢失了,所以写要加锁,也就是一个一个来,串行写。
Java集合框架里采用CopyOnWrite 机制的就两个类,

当然我们也可以定义自己的CopyOnWrite数据结构,
看下CopyOnWriteArrayList 的读写吧
读很直接,就读对象中当前引用的数组。
// Positional Access Operations
@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
return (E) a[index];
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
return get(getArray(), index);
}
set add remove 就需要加锁了,而且操作的是copy的副本。
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();
}
}

Copy-On-Write机制通过写时复制实现读写分离,保证并发读读和读写的并行性,但写写操作需串行进行。Java中CopyOnWriteArrayList利用此机制,读操作直接访问原始数组,而写操作会创建副本并加锁修改。由于迭代器基于快照,所以只支持读,适合读多写少的场景。对比其他选项,如SynchronizedList和Vector,CopyOnWriteArrayList在并发环境下提供更好的性能。
最低0.47元/天 解锁文章
2281

被折叠的 条评论
为什么被折叠?



