public class CopyOnWriteArrayList {
private transient volatile Object[] array;
public boolean add(E e) {
// 貌似定义一个本地变量指向属性,对性能会有优化?
// https://stackoverflow.com/questions/3866537/why-j-u-c-copyonwritearraylist-creates-local-lock-variable-inside-methods
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();
}
}
public boolean addIfAbsent(E e)
Object[] snapshot = getArray();
// 调用了indexOf检查元素的存在,实质上是遍历,性能不好
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
// indexOf使用了遍历,性能不好
private static int indexOf(Object o, Object[] elements,
int index, int fence) {
if (o == null) {
for (int i = index; i < fence; i++)
if (elements[i] == null)
return i;
} else {
for (int i = index; i < fence; i++)
if (o.equals(elements[i]))
return i;
}
return -1;
}
}
网友评论