一尘不染

什么时候CopyOnWriteArraySet对实现线程安全的HashSet有用?

java

Java,没有线程安全版本的HashMap命名的ConcurrentHashMap和线程安全版本TreeMap的命名ConcurrentSkipListMap,但没有ConcurrentHashSetHashSet的

相反,通常有4种使用线程安全的方法Set

  1. Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
  2. Set<String> s = Collections.synchronizedSet(new HashSet<String>());
  3. ConcurrentSkipListSet<E>
  4. CopyOnWriteArraySet<E>

1所使用keySet()ConcurrentHashMap同时实现Set和线程安全的。

2使用synchronized方式,似乎不推荐这种方式。

3是基于ConcurrentSkipListMap并被广泛使用的。

4是基于CopyOnWriteArrayList的,因此它具有的相同基本属性CopyOnWriteArrayList。以下是从CopyOnWriteArraySet文档中选择的内容:http
:
//docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html

  • 它最适合于集大小通常较小的应用,只读操作远远多于可变操作,并且您需要防止遍历期间线程之间的干扰。
  • 这是线程安全的。
  • 可变操作(添加,设置,删除等)非常昂贵,因为它们通常需要复制整个基础数组。
  • 迭代器不支持可变删除操作。
  • 通过迭代器进行遍历的速度很快,并且不会遇到其他线程的干扰。
  • 迭代器在构造迭代器时依赖于数组的不变快照。

由于通常使用1和3,为什么CopyOnWriteArraySet存在?什么时候CopyOnWriteArraySet有用?

补充:
CopyOnWriteArraySet基于CopyOnWriteArrayList,数据结构中的contains运算List为O(n),而Set数据结构用于高性能contains运算,有人可以解释吗?


阅读 404

收藏
2020-12-03

共1个答案

一尘不染

当您有少量的线程安全集合元素时,此功能很有用。

一个示例是一组侦听器。您需要确保唯一性并有效地遍历它们。

BTW CopyOnWriteArraySet在每个引用的基础上具有最低的开销。大小可能只有其他集合的1/6。如果您有很多,这特别有用。

虽然Set数据结构是为了高性能而包含操作,但是有人可以解释吗?

就内存而言,COWAS效率contains更高,对于小型集合,COWAS的速度比其他方法要快。什么是“高性能”取决于使用情况。

2020-12-03