“写时复制”——要写的时候复制一份副本,往副本里面写,然后引用到这个副本,在引用到这个副本之前有读操作的话,读的还是之前的老版本,读写分离,写不影响读可以并发读读,读写,但是写写的时候还是冲突的,如果拷贝了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 {