Java中的CopyOnWriteArraySet

Java中的CopyOnWriteArraySet

CopyOnWriteArraySet 是Java集合框架的成员之一。它是一个使用内部CopyOnWriteArrayList进行所有操作的Set。它在JDK 1.5中引入,可以说它是Set的线程安全版本。要使用此类,我们需要从java.util.concurrent包中导入它。

Java中的CopyOnWriteArraySet

它共享Set的一些属性,并具有其自己的属性,如下所列:

  • CopyOnWriteArraySet的内部实现仅是CopyOnWriteArrayList。
  • 多个线程能够同时执行更新操作,但对于每个更新操作,都会创建一个单独的克隆副本。由于每次更新都会创建新的克隆副本,因此不建议使用CopyOnWriteArraySet进行多个更新操作。
  • 当一个线程迭代Set时,其他线程可以执行更新操作,这里不会出现任何运行时异常,如ConcurrentModificationException。
  • CopyOnWriteArraySet类的迭代器只能执行只读操作,不应执行删除操作,否则我们将得到运行时异常UnsupportedOperationException。
  • 在应用程序中使用CopyOnWriteArraySet,其中集合大小通常保持较小,只读操作远远超过变异操作,并且在遍历期间需要防止线程干扰。
  • CopyOnWriteArraySet有助于最小化程序员控制的同步步骤,并将控制移动到内置的,经过充分测试的API中。

类层次结构如下:

java.lang.Object
   ↳ java.util.AbstractCollection<E>
        ↳ java.util.AbstractSet<E>
             ↳ java.util.concurrent.CopyOnWriteArraySet<E>

语法: 声明

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

在这里, E 是存储在此集合中的元素类型。它实现了 Serializable , **Iterable ** , **Collection ** ,Set接口。

CopyOnWriteArraySet的构造函数

1. CopyOnWriteArraySet() :创建一个空集。

CopyOnWriteArraySet<E> c = new CopyOnWriteArraySet<E>();

2. CopyOnWriteArraySet(Collection c) :创建包含指定集合中所有元素的集合。

CopyOnWriteArraySet<E> c = new CopyOnWriteArraySet<E>(Collection c);

例子:

// Java程序,演示CopyOnWriteArraySet类
 
// 导入所需类
import java.util.*;
import java.util.concurrent.*;
 
// 主类
class ConcurrentDemo extends Thread {
 
    static CopyOnWriteArraySet l
        = new CopyOnWriteArraySet();
 
    // 方法
    public void run()
    {
        // 子线程尝试在Set对象中添加新元素
        l.add("D");
    }
 
    // 方法2
    // 主驱动方法
    public static void main(String[] args)
    {
 
        // 使用add()方法添加元素
        l.add("A");
        l.add("B");
        l.add("C");
 
        // 我们创建一个子线程,修改CopyOnWriteArraySet l
        ConcurrentDemo t = new ConcurrentDemo();
 
        // 运行子线程
        t.start();
 
        // 等待线程添加元素
 
        // 尝试块检查异常
        try {
 
            Thread.sleep(2000);
        }
 
        // 捕获块以处理异常
        catch (InterruptedException e) {
 
            // 打印语句
            System.out.println(
                "child going to add element");
        }
 
        System.out.println(l);
 
        // 现在,我们通过CopyOnWriteArraySet迭代,并且我们不会得到异常
        Iterator itr = l.iterator();
 
        while (itr.hasNext()) {
 
            String s = (String)itr.next();
            System.out.println(s);
 
            if (s.equals("C")) {
 
                // 在此处,会抛出运行时异常
                itr.remove();
            }
        }
    }
}

输出:

Java中的CopyOnWriteArraySet

迭代CopyOnWriteArraySet

我们可以使用iterator()方法按照添加元素的顺序迭代此集合中包含的元素。返回的迭代器提供了构建迭代器时集合状态的不可变快照。由于这个属性, GeeksforGeeks 在第一次迭代时不会被输出。在迭代时不需要同步。迭代器不支持remove方法。

例子:

// Java程序,演示使用
// CopyOnWriteArraySet类进行迭代
 
// 导入所需的类
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
 
// 主类
// IteratingCopyOnWriteArraySet
class GFG {
 
    // 主函数
    public static void main(String[] args)
    {
 
        // 创建CopyOnWriteArraySet的实例
        CopyOnWriteArraySet<String> set
            = new CopyOnWriteArraySet<>();
 
        // 初始化一个迭代器
        Iterator itr = set.iterator();
 
        // 使用add()方法添加元素
        set.add("GeeksforGeeks");
 
        // 仅显示消息
        System.out.println("集合包含:");
 
        // 将集合的内容打印到控制台
        while (itr.hasNext())
            System.out.println(itr.next());
 
        // 添加了一个元素后的迭代器
        itr = set.iterator();
 
        // 仅显示消息
        System.out.println("集合包含:");
 
        // 将元素打印到控制台
        while (itr.hasNext())
            System.out.println(itr.next());
    }
}

输出:

集合包含:
集合包含:
GeeksforGeeks

CopyOnWriteArraySet中的方法

方法 行为
add(E e) 如果该集合中还没有该元素,则将指定元素添加到此集合中。
addAll(Collection c) | 将指定集合中的所有元素添加到此集合中,如果它们尚未存在于此集合中。
clear() | 从此集合中删除所有元素。
contains(Object o) | 如果此集合包含指定的元素,则返回true。
containsAll(Collection c)
如果此集合包含指定的集合中的所有元素,则返回true。
equals(Object o) 将指定对象与此集合进行比较以检查它们是否相等。
forEach(Consumer action) | 对Iterable的每个元素执行给定操作,直到所有元素都已处理完成或操作引发异常。
isEmpty() | 如果此集合不包含任何元素,则返回true。
iterator() | 按照添加这些元素的顺序,返回一个迭代器,该迭代器遍历此集合中包含的元素。
remove(Object o) | 如果存在,则从此集合中删除指定元素。
removeAll(Collection c)
从此集合中删除与指定集合中包含的元素相同的所有元素。
removeIf(Predicate filter) | 删除此集合的所有满足给定谓词的元素。
retainAll(Collection c)
仅保留此集合中包含在指定集合中的元素。
size() 返回此集合中的元素数。
spliterator() 按照添加这些元素的顺序,返回一个Spliterator,该Spliterator遍历此集合中包含的元素。
toArray() 返回包含此集合中所有元素的数组。
toArray(T[] a) 返回一个包含此集合中所有元素的数组,返回数组的运行时类型与指定数组的类型相同。

继承自java.util.AbstractSet类的方法

方法 描述
hashCode() 返回此集合的哈希码值。

继承自java.util.AbstractCollection类的方法

方法 描述
toString() 返回此集合的字符串表示形式。

继承自java.util.Collection接口的方法

方法 描述
parallelStream() 以此集合为源返回可能出现的并行Stream。
stream() 以此集合为源返回顺序Stream。

HashSet vs CopyOnWriteArraySet

PROPERTY HashSet CopyOnWriteArraySet
属于 java.util 包。 属于 java.util.concurrent 包。
同步 同步意味着只有一个线程可以访问或修改它。HashSet不同步。 它是同步的。
迭代器 由方法 iterator() 和 listiterator() 返回的迭代器是 fail-fast 。 返回的迭代器是 fail-safe 。
在版本中添加 它在JDK 1.2中添加。 它在JDK 1.5中添加。
性能 它很快,因为它不同步。 它比HashSet慢,因为它是同步的。
异常 它可能会抛出ConcurrentModificationException,因为许多线程可以同时访问它。 它不会抛出ConcurrentModificationException,因为它是同步的。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程