原文: https://howtodoinjava.com/java/collections/java-copyonwritearraylist/
Java CopyOnWriteArrayList是ArrayList的线程安全变体,其中的所有可变操作(添加,设置等)均通过对基础数组进行全新复制来实现。
它的不可变快照式迭代器方法在创建迭代器时使用了对数组状态的引用。 这在遍历操作远远超过列表更新操作且我们不想同步遍历并且在更新列表时仍希望线程安全的用例中很有用。
Table of Contents1\. CopyOnWriteArrayList Hierarchy2\. CopyOnWriteArrayList Features3\. CopyOnWriteArrayList Example4\. CopyOnWriteArrayList Constructors5\. CopyOnWriteArrayList Methods6\. CopyOnWriteArrayList Usecases7\. CopyOnWriteArrayList Performance8\. Conclusion
1. CopyOnWriteArrayList层次结构
CopyOnWriteArrayList类实现以下接口 – List,RandomAccess,Cloneable和serializable。
public class CopyOnWriteArrayList<E>implements List<E>,RandomAccess,Cloneable,Serializable{private transient volatile Object[] array;//implementation}
2. CopyOnWriteArrayList特性
有关 Java CopyOnWriteArrayList类的重要知识是:
CopyOnWriteArrayList类实现List和RandomAccess接口,因此提供ArrayList类中可用的所有特性。- 使用
CopyOnWriteArrayList进行更新操作的成本很高,因为每个突变都会创建基础数组的克隆副本,并为其添加/更新元素。 - 它是
ArrayList的线程安全版本。 每个访问列表的线程在初始化此列表的迭代器时都会看到自己创建的后备数组快照版本。 - 因为它在创建迭代器时获取基础数组的快照,所以它不会抛出
ConcurrentModificationException。 - 不支持对迭代器的删除操作(删除,设置和添加)。 这些方法抛出
UnsupportedOperationException。 CopyOnWriteArrayList是同步列表的并发替代,当迭代次数超过突变次数时,它提供了更好的并发性。- 它允许重复的元素和异构对象(使用泛型来获取编译时错误)。
- 因为它每次创建迭代器时都会创建一个数组的新副本,所以性能比
ArrayList慢。
3. CopyOnWriteArrayList示例
显示在不同时间创建的迭代器如何查看CopyOnWriteArrayList中list的快照版本的 Java 程序。 在给定的示例中,当列表具有元素(1,2,3)时,我们首先创建了list和itr1。
然后,我们在列表中添加了另一个元素,并再次创建了一个迭代器itr2。
最后,我们验证了两个迭代器中的元素。
CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>(new Integer[] {1,2,3});System.out.println(list); //[1, 2, 3]//Get iterator 1Iterator<Integer> itr1 = list.iterator();//Add one element and verify list is updatedlist.add(4);System.out.println(list); //[1, 2, 3, 4]//Get iterator 2Iterator<Integer> itr2 = list.iterator();System.out.println("====Verify Iterator 1 content====");itr1.forEachRemaining(System.out :: println); //1,2,3System.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. CopyOnWriteArrayList构造器
CopyOnWriteArrayList():创建一个空列表。CopyOnWriteArrayList(Collection c):创建一个列表,其中包含指定集合的元素,并按集合的迭代器返回的顺序排列。CopyOnWriteArrayList(object[] array):创建一个保存给定数组副本的列表。
5. CopyOnWriteArrayList方法
CopyOnWriteArrayList类支持ArrayList类支持的所有方法。 该行为仅在迭代器(快照迭代器)和列表中发生突变时创建的新支持数组的情况下有所不同。
此外,它提供了一些此类之外的方法。
boolean addIfAbsent(Object o):如果不存在,则追加元素。int addAllAbsent(Collection c):按指定集合的迭代器返回的顺序,将指定集合中尚未包含在此列表中的所有元素追加到此列表的末尾 。
对于所有受支持的其他方法,请访问ArrayList方法部分。
6. Java CopyOnWriteArrayList用例
在以下情况下,我们更喜欢使用CopyOnWriteArrayList而不是常规ArrayList:
- 当在并发环境中使用列表时。
- 迭代次数超过了变异操作的次数。
- 迭代器在创建时必须具有列表的快照版本。
- 我们不想以编程方式同步线程访问。
7. Java CopyOnWriteArrayList性能
由于每次更新列表时都要增加创建新支持数组的步骤,因此其性能比ArrayList差。
读取操作没有性能开销,并且两个类执行相同的操作。
8. 总结
在此 Java 集合教程中,我们学习了使用CopyOnWriteArrayList类,它的构造器,方法和用例。 我们学习了CopyOnWriteArrayList内部在 Java 中的工作原理以及CopyOnWriteArrayList与同步ArrayList的工作原理。
我们通过 Java CopyOnWriteArrayList示例程序演示了快照迭代器的工作方式。
在评论中把您的问题交给我。
学习愉快!
参考:
