原文: https://howtodoinjava.com/java/collections/java-copyonwritearrayset/

Java CopyOnWriteArraySetHashSet线程安全变体,其所有操作均使用基础CopyOnWriteArrayList

CopyOnWriteArrayList类似,它的不可变快照式迭代器方法在创建迭代器时使用对数组状态(在后备列表内)的引用。 这在遍历操作远远超过集合更新操作且我们不想同步遍历并且在更新集合时仍希望线程安全的用例中很有用。

  1. Table of Contents
  2. 1\. CopyOnWriteArraySet Hierarchy
  3. 2\. CopyOnWriteArraySet Features
  4. 3\. CopyOnWriteArraySet Example
  5. 4\. CopyOnWriteArraySet Constructors
  6. 5\. CopyOnWriteArraySet Methods
  7. 6\. CopyOnWriteArraySet Usecases
  8. 7\. CopyOnWriteArraySet Performance
  9. 8\. Conclusion

1. CopyOnWriteArraySet层次结构

CopyOnWriteArraySet类扩展了AbstractSet类并实现了Serializable接口。

public class CopyOnWriteArraySet<E>
        extends AbstractSet<E>
        implements Serializable

{
    private final CopyOnWriteArrayList<E> al;

    //implementation
}

2. CopyOnWriteArraySet特性

有关 Java CopyOnWriteArraySet类的重要知识是:

  • 作为正常设置的数据结构,它不允许重复。
  • CopyOnWriteArraySet类实现Serializable接口并扩展AbstractSet类。
  • 使用CopyOnWriteArraySet进行更新操作成本很高,因为每个突变都会创建基础数组的克隆副本并向其添加/更新元素。
  • 它是HashSet的线程安全版本。 每个访问该集合的线程在初始化此集合的迭代器时都会看到自己创建的后备数组快照版本。
  • 因为它在创建迭代器时获取基础数组的快照,所以它不会抛出ConcurrentModificationException
  • 不支持迭代器上的变异操作。 这些方法抛出UnsupportedOperationException
  • CopyOnWriteArraySet同步集的并发替代,并且在迭代次数超过突变次数时提供了更好的并发性。
  • 它允许重复的元素和异构对象(使用泛型来获取编译时错误)。
  • 因为它每次创建迭代器时都会创建基础数组的新副本,所以性能比HashSet

3. Java CopyOnWriteArraySet示例

Java 程序,用于显示在不同时间创建的迭代器如何查看CopyOnWriteArraySet中集合的快照版本。 在给定的示例中,当列表具有元素(1,2,3)时,我们首先创建了listitr1

然后,我们在列表中添加了另一个元素,并再次创建了一个迭代器itr2

最后,我们验证了两个迭代器中的元素。

CopyOnWriteArraySet<Integer> set = new CopyOnWriteArraySet<>(Arrays.asList(1,2,3));

System.out.println(set);    //[1, 2, 3]

//Get iterator 1
Iterator<Integer> itr1 = set.iterator();

//Add one element and verify set is updated
set.add(4);
System.out.println(set);    //[1, 2, 3, 4]

//Get iterator 2
Iterator<Integer> itr2 = set.iterator();

System.out.println("====Verify Iterator 1 content====");

itr1.forEachRemaining(System.out :: println);    //1,2,3

System.out.println("====Verify Iterator 2 content====");

itr2.forEachRemaining(System.out :: println);    //1,2,3,4

程序输出。

[1, 2, 3]
[1, 2, 3, 4]
====Verify Iterator 1 content====
1
2
3
====Verify Iterator 2 content====
1
2
3
4

4. CopyOnWriteArraySet构造器

  • CopyOnWriteArraySet():创建一个空集。
  • CopyOnWriteArraySet(Collection c):创建一个包含指定集合元素的集合,其顺序由集合的迭代器返回。

5. CopyOnWriteArraySet方法

  • boolean add(object o):如果指定的元素尚不存在,则将其添加到此集合中。
  • boolean addAll(collection c):将指定集合中的所有元素(如果尚不存在)添加到此集合中。
  • void clear():从该集合中删除所有元素。
  • boolean contains(Object o):如果此集合包含指定的元素,则返回 true。
  • boolean isEmpty():如果此集合不包含任何元素,则返回 true。
  • Iterator iterator():以添加这些元素的顺序在此集合中包含的元素上返回一个迭代器。
  • boolean remove(Object o):如果存在指定元素,则从此集合中删除该元素。
  • int size():返回此集合中的元素数。

6. Java CopyOnWriteArraySet用例

在集大小通常保持较小的应用程序中使用CopyOnWriteArraySet,只读操作大大超过了可变操作,并且您需要防止遍历期间线程之间的干扰。

CopyOnWriteArraySet有助于最小化程序员控制的同步步骤,并将控制权移交给经过良好测试的内置 API。

7. Java CopyOnWriteArraySet性能

由于每次更新集时都会增加创建新支持数组的步骤,因此其性能比HashSet差。
读取操作没有性能开销,并且两个类执行相同的操作。

8. 总结

在本 Java 集合教程中,我们学习了使用CopyOnWriteArraySet类,其构造器,方法和用例。

我们了解了在 Java 中CopyOnWriteArraySet的内部工作原理,以及CopyOnWriteArraySetCopyOnWriteArrayList的工作原理。

我们通过 Java CopyOnWriteArraySet示例程序演示了快照迭代器的工作方式。

在评论中把您的问题交给我。

学习愉快!

参考:

CopyOnWriteArraySet Java 文档