Java CopyOnWriteArraySet类使用教程

x33g5p2x  于2021-08-22 转载在 Java  
字(3.7k)|赞(0)|评价(0)|浏览(491)

CopyOnWriteArraySet类概述

在这篇文章中,我们将讨论来自java.util.concurrent包的CopyOnWriteArraySet

在多线程程序中,这是一个非常有用的结构--当我们想以线程安全的方式迭代一个集合时,不需要明确的[2$]。
一个CopyOnWriteArraySet,它的所有操作都使用内部的CopyOnWriteArrayList。因此,它具有相同的基本属性。

  • 它最适合于这样的应用:集合的大小通常保持较小,只读操作远远超过突变操作,并且你需要在遍历过程中防止线程之间的干扰。
  • 它是线程安全的。
  • 突变操作(添加、设置、删除等)很昂贵,因为它们通常需要复制整个底层数组。
  • 迭代器不支持互换的删除操作。
  • 通过迭代器进行的遍历是快速的,不能遇到其他线程的干扰。迭代器依赖于在构建迭代器时数组的不变快照。
    CopyOnWriteArraySet类是Java集合框架的一个成员

我们将学到什么?

  1. CopyOnWriteArraySet类构造函数概要
  2. CopyOnWriteArraySet类方法总结
  3. CopyOnWriteArraySet类的例子

1. CopyOnWriteArraySet类构造函数摘要

  • CopyOnWriteArraySet() - 创建一个空集。
  • CopyOnWriteArraySet(Collection<? extends E> c) - 创建一个包含指定集合中所有元素的集合。

2. CopyOnWriteArraySet类方法总结

  • boolean add(E e) - 将指定的元素添加到这个集合中,如果它还没有存在的话。
  • boolean addAll(Collection<? extends E> c) - 将指定集合中的所有元素添加到这个集合中,如果它们还不存在的话。
  • void clear() - 从这个集合中删除所有的元素。
  • boolean contains(Object o) - 如果这个集合包含指定的元素,返回真。
  • boolean containsAll(Collection<?> c) - 如果这个集合包含指定集合的所有元素,则返回真。
  • boolean equals(Object o) - 将指定的对象与这个集合进行比较,看是否相等。
  • void forEach(Consumer<? super E> action) - 对Iterable的每个元素执行给定的动作,直到所有的元素都被处理完,或者该动作抛出一个异常。
  • boolean isEmpty() - 如果这个集合不包含任何元素,则返回true。
  • Iterator iterator()- 返回这个集合中包含的元素的迭代器,其顺序是这些元素被添加的顺序。
  • boolean remove(Object o) - 从这个集合中删除指定的元素,如果它存在的话。
  • boolean removeAll(Collection<?> c) - 从这个集合中删除所有包含在指定集合中的元素。
  • boolean removeIf(Predicate<? super E> filter) - 移除此集合中满足给定谓词的所有元素。
  • boolean retainAll(Collection<?> c) - 只保留这个集合中包含在指定集合中的元素。
  • int size() - 返回这个集合中元素的数量。
  • Spliterator spliterator() - 返回这个集合中的元素的Spliterator,按照这些元素被添加的顺序。
  • Object[] toArray() - 返回一个包含这个集合中所有元素的数组。
  • T[] toArray(T[] a) - 返回一个包含这个集合中所有元素的数组; 返回的数组的运行时类型是指定数组的类型

3. CopyOnWriteArraySet类示例

让我们看一下简单的例子来演示如何使用

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;

//*/*
/* This program demonstrates how a CopyOnWriteArraySet works in multi-threading
/* context.
/*
/* @author www.javaguides.net
/*/

public class CopyOnWriteArraySetExample {

    public static void main(final String[] args) {

       final CopyOnWriteArraySet<Integer> set = new CopyOnWriteArraySet<>();

       set.add(1);
       set.add(2);
       set.add(3);
       set.add(4);
       set.add(5);

       final Runnable runnable = () -> {
             set.add(4);
             set.add(5);
       };
  
       final Thread thread = new Thread(runnable);
       thread.start();
  
       final Iterator<Integer> iterator = set.iterator();
       while (iterator.hasNext()) {
             final Integer integer = iterator.next();
             System.out.println(integer);
       }
   }
}

输出:

1
2
3
4
5

还有一个来自JavaDoc的例子:下面的代码草图使用一个写时拷贝集来维护一组处理程序对象,在状态更新时执行一些动作。

class Handler {
    void handle() {

    };
}

class X {
      private final CopyOnWriteArraySet<Handler> handlers = new CopyOnWriteArraySet<Handler>();

      public void addHandler(final Handler h) {
         handlers.add(h);
      }

      private long internalState;

      private synchronized void changeState() {
           internalState = 10;
      }

      public void update() {
          changeState();
          for (final Handler handler : handlers)
              handler.handle();
      }
}

迭代时不允许删除

要知道这个集合类的迭代器不支持remove()操作,试图在迭代时删除一个元素会导致UnSupportedOperationException

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;

//*/*
/* This program demonstrates how a CopyOnWriteArraySet works in multi-threading
/* context.
/*
/* @author www.javaguides.net
/*/

public class CopyOnWriteArraySetExample {

       public static void main(final String[] args) {

       final CopyOnWriteArraySet<Integer> set = new CopyOnWriteArraySet<>();

       set.add(1);
       set.add(2);
       set.add(3);
       set.add(4);
       set.add(5);

       final Runnable runnable = () -> {
            set.add(4);
            set.add(5);
       };
  
       final Thread thread = new Thread(runnable);
       thread.start();
  
       final Iterator<Integer> iterator = set.iterator();
       while (iterator.hasNext()) {
             final Integer integer = iterator.next();
             iterator.remove();
             System.out.println(integer);
       }
    }
}

输出:

Exception in thread "main" java.lang.UnsupportedOperationException
 at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1178)
 at com.javaguides.collections.specialpurposeimpl.CopyOnWriteArraySetExample
.main(CopyOnWriteArraySetExample.java:36)

###参考文献

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArraySet.html

相关文章