前文转载过一遍博文关于CopyOnWriteArrayList使用,地址在:http://blog.csdn.net/dax1n/article/details/69396373
CopyOnWriteArraySet也是一个Copy-On-Write容器,关于Copy-On-Write容器不懂看http://blog.csdn.net/dax1n/article/details/69396373。
文本将学习一下CopyOnWriteArraySet的使用和原理实现,CopyOnWriteArraySet是一个支持并发访问的容器,接下来我们就看看其使用和实现:
public class CopyOnWriteArraySetMain {
public static void main(String[] args) {
CopyOnWriteArraySet cset = new CopyOnWriteArraySet<>();
Integer in = new Integer(1);
cset.add(in);
cset.add(2);
cset.add(3);
cset.add(4);
cset.add(5);
System.out.println(cset.size());
}
}
public boolean add(E e) {
return al.addIfAbsent(e);
}
public class CopyOnWriteArraySet extends AbstractSet
implements java.io.Serializable {
private static final long serialVersionUID = 5457747651344034263L;
private final CopyOnWriteArrayList al; //声明al
/**
* Creates an empty set.
*/
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList(); //初始化al
}
//省略部分代码
}
public boolean addIfAbsent(E e) {//这个方法容器如果存在则直接返回,不存在的话在执行添加
Object[] snapshot = getArray();
//indexOf方法:是在snapshot数组的0到snapshot.length搜索元素e,如果不存在返回false,否则执行addIfAbsent方法
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
接下来看看java.util.concurrent.CopyOnWriteArrayList.addIfAbsent(E, Object[])实现:
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
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;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
总结:
CopyOnWriteArraySet的实现是借助CopyOnWriteArrayList实现的,只不过CopyOnWriteArraySet是在CopyOnWriteArrayList上使用indexOf不允许存入重复元素,正好符合Set的特性!