📌  相关文章
📜  Java中的 CopyOnWriteArraySet

📅  最后修改于: 2022-05-13 01:55:21.498000             🧑  作者: Mango

Java中的 CopyOnWriteArraySet

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

java中的CopyOnWriteArraySet

它共享 Set 的一些属性,也有自己的属性,如下所示:

  • CopyOnWriteArraySet 的内部实现仅为 CopyOnWriteArrayList。
  • 多个线程能够同时执行更新操作,但对于每个更新操作,都会创建一个单独的克隆副本。至于每次更新都会创建一个新的克隆副本,这是昂贵的。因此,如果需要多次更新操作,则不建议使用 CopyOnWriteArraySet。
  • 当一个线程迭代 Set 时,其他线程可以执行更新,这里我们不会得到像 ConcurrentModificationException 这样的运行时异常
  • CopyOnWriteArraySet 类的 Iterator 只能执行只读,不应该执行删除,否则会得到 Run-time exception UnsupportedOperationException
  • 在集合大小通常保持较小、只读操作大大超过可变操作的应用程序中使用 CopyOnWriteArraySet,并且您需要在遍历期间防止线程之间的干扰。
  • CopyOnWriteArraySet 有助于最大限度地减少程序员控制的同步步骤并将控制转移到内置的、经过良好测试的 API。

类层次结构如下:

java.lang.Object
   ↳ java.util.AbstractCollection
        ↳ java.util.AbstractSet
             ↳ java.util.concurrent.CopyOnWriteArraySet

语法:声明

public class CopyOnWriteArraySet extends AbstractSet implements Serializable

这里, E是存储在此 Collection 中的元素的类型。它实现了 SerializableIterableCollection 、 Set 接口。

CopyOnWriteArraySet 的构造函数

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

CopyOnWriteArraySet c = new CopyOnWriteArraySet();

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

CopyOnWriteArraySet c = new CopyOnWriteArraySet(Collection c);

例子:

Java
// 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
// 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 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());
    }
}


输出:

遍历 CopyOnWriteArraySet

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

例子:

Java

// 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 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 中的方法

Method

Action Performed

add(E e)Adds the specified element to this set if it is not already present.
addAll(Collection c)Adds all of the elements in the specified collection to this set if they’re not already present.
clear()Removes all of the elements from this set.
contains(Object o)Returns true if this set contains the specified element.
containsAll(Collection c)Returns true if this set contains all of the elements of the specified collection.
equals(Object o)Compares the specified object with this set for equality.
forEach(Consumer action)Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.
isEmpty()Returns true if this set contains no elements.
 iterator()Returns an iterator over the elements contained in this set in the order in which these elements were added.
remove(Object o)Removes the specified element from this set if it is present.
removeAll(Collection c)Removes from this set all of its elements that are contained in the specified collection.
removeIf(Predicate filter)Removes all of the elements of this collection that satisfy the given predicate.
retainAll(Collection c)Retains only the elements in this set that are contained in the specified collection.
size()Returns the number of elements in this set.
spliterator()Returns a Spliterator over the elements in this set in the order in which these elements were added.
toArray()Returns an array containing all of the elements in this set.
toArray(T[] a)Returns an array containing all of the elements in this set; the runtime type of the returned array is that of the specified array.

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

METHOD

DESCRIPTION

hashCode()Returns the hash code value for this set.

从类Java.util.AbstractCollection 继承的方法

METHOD

DESCRIPTION

toString()Returns a string representation of this collection.

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

METHOD

DESCRIPTION

parallelStream()Returns a possibly parallel Stream with this collection as its source.
stream()Returns a sequential Stream with this collection as its source.

HashSet 与 CopyOnWriteArraySet

PROPERTY

HashSet

CopyOnWriteArraySet

PackageIt belongs to java.util packageIt belongs to java.util.concurrent package
SynchronizationSynchronization means only one thread can access or modify it. HashSet is not synchronized.It is synchronized.
IteratorsIterators returned my methods iterator() and listiterator() are fail-fast.Iterators returned are fail-safe.
Added In VersionIt was added in JDK 1.2It was added in JDK  1.5
PerformanceIt is fast since it is not synchronized.It is slower compared to HashSet since it is synchronized.
ExceptionIt may throw ConcurrentModificationException since many threads can access it simultaneously. It does not throws ConcurrentModificationException since it is synchronized.