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 Program to Illustrate CopyOnWriteArraySet Class
 
// Importing required classes
import java.util.*;
import java.util.concurrent.*;
 
// Main class
class ConcurrentDemo extends Thread {
 
    static CopyOnWriteArraySet l
        = new CopyOnWriteArraySet();
 
    // Method
    public void run()
    {
        // Child thread trying to add
        // new element in the Set object
        l.add("D");
    }
 
    // Method 2
    // Main driver method
    public static void main(String[] args)
    {
 
        // Adding elements
        // using add() method
        l.add("A");
        l.add("B");
        l.add("C");
 
        // We create a child thread
        // that is going to modify
        // CopyOnWriteArraySet l.
        ConcurrentDemo t = new ConcurrentDemo();
 
        // Running the child thread
        // using start() method
        t.start();
 
        // Waiting for the thread to
        // add the element
 
        // Try block to check for exceptions
        try {
 
            Thread.sleep(2000);
        }
 
        // Catch block to handle exceptions
        catch (InterruptedException e) {
 
            // Print statement
            System.out.println(
                "child going to add element");
        }
 
        System.out.println(l);
 
        // Now we iterate through the
        // CopyOnWriteArraySet and we
        // wont get exception.
        Iterator itr = l.iterator();
 
        while (itr.hasNext()) {
 
            String s = (String)itr.next();
            System.out.println(s);
 
            if (s.equals("C")) {
 
                // Here we will get
                // RuntimeException
                itr.remove();
            }
        }
    }
}

输出

Java中的CopyOnWriteArraySet

迭代 CopyOnWriteArraySet

我们可以使用iterator()方法按照这些元素被添加的顺序遍历这个集合中的元素。返回的迭代器提供了一个不可改变的快照,即迭代器构建时的集合状态。因为这个属性, GeeksforGeeks 不会在第一次迭代时被打印出来。迭代时不需要同步。该迭代器不支持移除方法。

例子

// Java program to Illustrate Iterating Over
// CopyOnWriteArraySet class
 
// Importing required classes
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
 
// Main class
// IteratingCopyOnWriteArraySet
class GFG {
 
    // Main class
    public static void main(String[] args)
    {
 
        // Creating an instance of CopyOnWriteArraySet
        CopyOnWriteArraySet<String> set
            = new CopyOnWriteArraySet<>();
 
        // Initial an iterator
        Iterator itr = set.iterator();
 
        // Adding elements
        // using add() method
        set.add("GeeksforGeeks");
 
        // Display message only
        System.out.println("Set contains: ");
 
        // Printing the contents
        // of set to the console
        while (itr.hasNext())
            System.out.println(itr.next());
 
        // Iterator after adding an element
        itr = set.iterator();
 
        // Display message only
        System.out.println("Set contains:");
 
        // Printing the elements to the console
        while (itr.hasNext())
            System.out.println(itr.next());
    }
}

输出

Set contains: 
Set contains:
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,按照这些元素被添加的顺序。
toArray() 返回一个包含这个集合中所有元素的数组。
toArray(T[] a) 返回一个包含这个集合中所有元素的数组;返回的数组的运行时类型是指定数组的类型。

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

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

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

方法 描述
toString() 返回这个集合的字符串表示。

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

方法 描述
parallelStream() 返回一个以该集合为源的可能的并行流。
stream() 返回一个以这个集合为源的顺序流。

HashSet vs CopyOnWriteArraySet

属性 哈希集 写入数组上的复制(CopyOnWriteArraySet
它属于java.util包 它属于java.util.concurrent包。
同步化 同步意味着只有一个线程可以访问或修改它。HashSet是不同步的。 它是同步的。
迭代器 我的方法iterator()和listiterator()返回的迭代器是故障快速的。 返回的迭代器是故障安全的。
添加在版本中 在JDK 1.2中添加 在JDK 1.5中添加
性能表现 因为它不是同步的,所以速度很快。 与HashSet相比,它要慢一些,因为它是同步的。
异常 它可能会抛出ConcurrentModificationException,因为许多线程可以同时访问它。 因为它是同步的,所以不会抛出ConcurrentModificationException。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程