添加操作
final Object[] getArray() {
return array;
}
final void setArray(Object[] a) {
array = a;
}
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();
}
}
加锁,否则会copy出很多副本
读取数据
final Object[] getArray() {
return array;
}
private E get(Object[] a, int index) {
return (E) a[index];
}
public E get(int index) {
return get(getArray(), index);
}
读的时候不用加锁,读到的为原来的数据(可重复读:一个事务在执行过程中,看到的数据和事务启动时一致)
使用场景
- 读多写少
缺点
- 数据无法保证实时一致性
- 由于写时复制,可能存在多个对象,会引起频繁的young gc 和 full gc
其他
虽然java只提供了List和Set的版本,但是其实大体上都是一样的,写-复制-更新。(避免锁)