CopyOnWriteArraySet 源码分析
CopyOnWriteArraySet 源码分析:
1:数据结构:
private final CopyOnWriteArrayList<E> al; 内部维护的是一个CopyOnWriteArrayList,所以CopyOnWriteArraySet的实现原理是通过CopyOnWriteArrayList的机制来实现的;
2:构造方法:
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
创建一个空的CopyOnWriteArrayList集合,回到CopyOnWriteArrayList中,这个构造方法有两个作用:
1):setArray(new Object[0]); 新建一个长度为0的Object数组,并且赋值给array变量;
2):final transient ReentrantLock lock = new ReentrantLock();实例化一个独占锁对象;
3:方法分析,这里主要分析 add get remove 这几个常用的方法:
1):addd方法源码分析:
public boolean add(E e) {
return al.addIfAbsent(e);
}
内部调用CopyOnWriteArrayList 的addIfAbsent方法;
下面对addIfAbsent这个方法进行分析:
public boolean addIfAbsent(E e) { //e=”beppe”
Object[] snapshot = getArray(); // snapshot= Object[0]
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
接下来分析indexOf(e, snapshot, 0, snapshot.length) 这个方法:
private static int indexOf(Object o, Object[] elements,
int index, int fence) { //o=”beppe” elements=Object[]
index=0 fence=0
if (o == null) { //插入空值的场景
for (int i = index; i < fence; i++)
if (elements[i] == null) //如果集合中之前有 null 元素存在则返回 i
return i;
} else { //非空值插入场景
for (int i = index; i < fence; i++)
if (o.equals(elements[i]))
return i;
}
return -1;
}
indexOf() 这个方法的作用是判断需要添加的元素在集合中是否存在,若存在则返回该元素的索引,主要用于去重使用;
如果集合中没有重复元素,则返回-1;下面分析addIfAbsent(e, snapshot)这个方法
集合add 首个元素为例:
private boolean addIfAbsent(E e, Object[] snapshot) { //e=”beppe1” snapshot=Object[0]
final ReentrantLock lock = this.lock;
lock.lock(); //获取独占锁
try {
Object[] current = getArray(); // current=Object[0],当线程并发写入时 获取最新的数组值,这里主要是为了获取最新的数组
int len = current.length; //len=0
if (snapshot != current) { //说明这里并发操作
// Optimize for lost race to another addXXX operation
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
//对数组进行动态扩容 copy 当前数组到 新数组中
Object[] newElements = Arrays.copyOf(current, len + 1);
//将新元素赋值到新的数组中
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock(); //解锁
}
}
4:remove方法:
public boolean remove(Object o) {
return al.remove(o); // al 是一个CopyOnWriteArrayList 对象,这里就是执行CopyOnWriteArrayList的remove方法
}
public boolean remove(Object o) {
Object[] snapshot = getArray();
int index = indexOf(o, snapshot, 0, snapshot.length);
return (index < 0) ? false : remove(o, snapshot, index);
}
说明:CopyOnWriteArraySet 内部维护的是一个 CopyOnWriteArrayList 数据结构,其原理和CopyOnWriteArrayList 的实现原理是一致的;