原文: https://howtodoinjava.com/java/collections/java-copyonwritearrayset/
Java CopyOnWriteArraySet
是HashSet
的线程安全变体,其所有操作均使用基础CopyOnWriteArrayList
。
与CopyOnWriteArrayList
类似,它的不可变快照式迭代器方法在创建迭代器时使用对数组状态(在后备列表内)的引用。 这在遍历操作远远超过集合更新操作且我们不想同步遍历并且在更新集合时仍希望线程安全的用例中很有用。
Table of Contents
1\. CopyOnWriteArraySet Hierarchy
2\. CopyOnWriteArraySet Features
3\. CopyOnWriteArraySet Example
4\. CopyOnWriteArraySet Constructors
5\. CopyOnWriteArraySet Methods
6\. CopyOnWriteArraySet Usecases
7\. CopyOnWriteArraySet Performance
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
)时,我们首先创建了list
和itr1
。
然后,我们在列表中添加了另一个元素,并再次创建了一个迭代器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
的内部工作原理,以及CopyOnWriteArraySet
与CopyOnWriteArrayList
的工作原理。
我们通过 Java CopyOnWriteArraySet
示例程序演示了快照迭代器的工作方式。
在评论中把您的问题交给我。
学习愉快!
参考: