Java 如何创建一个线程安全的ConcurrentHashSet

Java 如何创建一个线程安全的ConcurrentHashSet

在JDK 8之前,创建线程安全的ConcurrentHashSet是不可能的,因为java.util.concurrent包中没有一个叫做ConcurrentHashSet的类,但是从JDK 8开始,新增加的keySet(默认)和newKeySet()方法可以在Java中创建一个ConcurrentHashSet,而ConcurrentHashMap也支持。

并发HashSet 等。这些方法只能在ConcurrentHashMap类中使用,不能在ConcurrentMap接口中使用,所以我们需要使用ConcurrentHashMap引用变量来保存引用,或者我们可以使用类型转换来转换存储在ConcurrentMap变量中的ConcurrentHashMap对象。

这个方法的问题是只有一个map,没有set,不能用虚拟值对ConcurrentHashMap进行set操作。当一些方法需要一个Set时,你无法传递它,所以它的作用不大。

另一个选择是通过调用keySet()方法,keySet()方法实际上返回一个Set,其中可以执行和传递Set操作,但这个方法有其局限性,我们不能向这个keyset添加新元素,因为它会抛出一个UnsupportedOperationException。

由于所有这些限制,引入了newKeySet()方法,该方法返回一个由给定类型的ConcurrentHashMap支持的集合,其值为布尔值。

如何使用newKeyset()创建ConcurrentHashSet。

// Create the ConcurrentHashMap
ConcurrentHashMap<String, Integer> map
    = new ConcurrentHashMap<>();
 
// Create the set by newKeySet() method of ConcurrentHashMap
Set<String> set = map.newKeySet();
 
// add() method
set.add("geeksforgeeks");
set.add("geeks");
 
// contains() method to check whether the element present or
// not it will return boolean value (true or false)
set.contains("geeks");
 
// remove() method to remove an element from set
set.remove("geeksforgeeks");

上面提到的例子并不是在Java中创建线程安全的Set的唯一方法。

使用的ConcurrentHashSet

// Create ConcurrentHashMap
ConcurrentHashMap<String, Integer> map
    = new ConcurrentHashMap<>();
 
// Create Set using the map
Set<String> set
    = map.keySet(246); // 246 is any default value
 
set.add("GeeksForGeeks"); // Value will remain same as 246
                          // but we will get no error.
 
// We can use all the functions like contains(),remove(),etc.
// as discussed in the previous code snippet
// Create ConcurrentHashMap
ConcurrentHashMap<String, Integer> map
    = new ConcurrentHashMap<>();
 
// Create Set using the map
Set<String> set
    = map.keySet(246); // 246 is any default value
 
set.add("GeeksForGeeks"); // Value will remain same as 246
                          // but we will ge no error.
 
// We can use all the functions like contains(),remove(),etc.
// as discussed in the previous code snippet

实现。

// Java program to implement thread safe ConcurrentHashSet
 
import java.io.*;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
 
class GFG {
    public static void main (String[] args) {
       
        // Creating a map 
        ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
       
          map.put("Geeks",246);
          map.put("GeeksforGeeks",246);
          map.put("Java", 200);
          map.put("Java 8",200);
          map.put("Threads", 300);
           
          // Creating set using keySet()
          Set concSet = map.keySet();
       
          System.out.println("Initial set: " + concSet);
           
          // If we want to add element is the set like
          // concSet.add("Element"); this will throw an UnsupportedOperationExcetpion
         
          // Now as mentioned in the above format we have to
        // create the set using newKeySet()
          Set <String> penNameSet = ConcurrentHashMap.newKeySet();
         
        penNameSet.add("Flair");
        penNameSet.add("Reynolds");
        penNameSet.add("Cello");
       
          // Print the set
          System.out.println("before adding element into concurrent set: " + penNameSet);
       
          // Adding new Element in the set
          penNameSet.add("Classmate");
           
          // Print again to see the change
          System.out.println("after adding element into concurrent set: " + penNameSet);
           
          // Check element present or not
          if(penNameSet.contains("Reynolds"))
        {
          System.out.println("YES");
        }
          else
        {
          System.out.println("NO");
        }
           
          // We can check directly like this and it will return a boolean value
          System.out.println(penNameSet.contains("Reynolds"));
       
          // Remove any element from set
          penNameSet.remove("Cello");
          System.out.println("after removing element from concurrent set: "
                                    + penNameSet);
       
    }
}

输出

Initial set: [Threads, Java, GeeksforGeeks, Geeks, Java 8]
before adding element into concurrent set: [Cello, Reynolds, Flair]
after adding element into concurrent set: [Cello, Classmate, Reynolds, Flair]
YES
true
after removing element from concurrent set: [Classmate, Reynolds, Flair]

这些是在Java 8中创建ConcurrentHashSet的方法。JDK 8 API具有所有的主要功能,如lambda表达式和流,以及这些小的变化,使编写代码变得容易。

以下是CopyOnWriteArraySet的一些重要属性。

  • 它最适合于非常小的应用程序,只读操作的数量远远超过可变操作,而且有必要防止遍历过程中线程之间的干扰。
  • 它的线是安全的。
  • 栅格不支持变量删除操作。
  • 通过迭代器的遍历是快速的,不会遇到其他线程的干扰。
  • 在构建迭代器时,猛禽能够保持阵列的快照不变。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程