CopyOnWriteArrayList 写时拷贝
特点
- 写操作都会复制一个新的数组
- 线程安全
- 适用于高并发读,少量写的场景(读不需要加锁,写需要加锁)
- 读写分离
- 数据最终一致
源码
基于可重入锁和数组实现
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
private static final long serialVersionUID = 8673264195747942595L;
/** The lock protecting all mutators */
transient final ReentrantLock lock = new ReentrantLock();
/** The array, accessed only via getArray/setArray. */
private volatile transient Object[] array;
}
以新增为例,新增时先获取锁,然后复制原数组数据到一个新的长度加1的数组,将新元素加入到新数组,更改数组的引用。
新增时需要加锁,并且是操作的新数组,所以并不影响读操作,读时不需要加锁可以并发读,只是读的可能不是最新数据,但保证数据的最终一致性。
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();
}
}
CopyOnWriteArraySet 是基于 CopyOnWriteArrayList实现的并发Set集合