Java集合–CopyOnWriteArraySet

它是线程安全的无序的集合,可以将它理解成线程安全的​​HashSet​​​。有意思的是,CopyOnWriteArraySet和HashSet虽然都继承于共同的父类AbstractSet;但是,HashSet是通过​​“散列表​​​(HashMap)”实现的,而CopyOnWriteArraySet则是通过“​​动态数组​​​​(CopyOnWriteArrayList)​​”实现的,并不是散列表。

和CopyOnWriteArrayList类似,CopyOnWriteArraySet具有以下特性:

1. 它最适合于具有以下特征的应用程序:Set 大小通常保持很小,只读操作远多于可变操作,需要在遍历期间防止线程间的冲突。

2. 它是线程安全的。

3. 因为通常需要复制整个基础数组,所以可变操作(add()、set() 和 remove() 等等)的开销很大。

4. 迭代器支持hasNext(), next()等不可变操作,但不支持可变 remove()等 操作。

5. 使用迭代器进行遍历的速度很快,并且不会与其他线程发生冲突。在构造迭代器时,迭代器依赖于不变的数组快照。

 

CopyOnWriteArraySet的数据结构,如下图所示:

Java集合–CopyOnWriteArraySet插图

说明:
  1. CopyOnWriteArraySet继承于​​​AbstractSet​​​,这就意味着它是一个集合。
  2. CopyOnWriteArraySet包含​​​CopyOnWriteArrayList​​​对象,它是通过CopyOnWriteArrayList实现的。而CopyOnWriteArrayList本质是个动态数组队列,
所以CopyOnWriteArraySet相当于通过通过动态数组实现的“集合”! CopyOnWriteArrayList中允许有重复的元素;但是,CopyOnWriteArraySet是一个集合,所以它不能有重复集合。因此,CopyOnWriteArrayList额外提供了addIfAbsent()和addAllAbsent()这两个添加元素的API,通过这些API来添加元素时,只有当元素不存在时才执行添加操作!
   至于CopyOnWriteArraySet的“线程安全”机制,和​​​CopyOnWriteArrayList​​​一样,是通过volatile和互斥锁来实现的。这个在前一章节介绍​​CopyOnWriteArrayList​​时数据结构时,已经进行了说明,这里就不再重复叙述了。

CopyOnWriteArraySet最终的实现还是通过CopyOnWriteArrayList来实现的。

private final CopyOnWriteArrayListE> al;

CopyOnWriteArrayList提供了一个方法addIfAbsent添加值,如果不存在则添加,如果存在则不添加。

 

public boolean addIfAbsent(E e) {  
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}

 

 

 

 

 

 

文章来源于互联网:Java集合--CopyOnWriteArraySet

THE END
分享
二维码