Open In App

How to Create a Thread-Safe ConcurrentHashSet in Java?

Last Updated : 20 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Creating Thread Safe ConcurrentHashSet is not possible before JDK 8 because of the java.util.concurrent package does not have a class called ConcurrentHashSet, but starting with JDK 8, the newly added keySet (the default) and newKeySet() methods to create a ConcurrentHashSet in Java that is supported by ConcurrentHashMap.

ConcurrentHashSet can be created by using ConcurrentHashMap as it allows us to use keySet(default value) and newKeySet() methods to return the Set, which happens to be a proper Set. This gives us access to necessary functions like contains(), remove(), etc. These methods can only be used in the ConcurrentHashMap class and not in the ConcurrentMap interface, so we need to use the ConcurrentHashMap reference variable to hold the reference, or we can use a type conversion to convert the ConcurrentHashMap object stored in the ConcurrentMap variable.

The problem with this method is that there is only one map and no set, and it cannot perform a set operation on ConcurrentHashMap using virtual values. When some methods require a Set, you can’t pass it, so it’s not very useful.

Another option is by calling the keySet() method and the keySet() method actually returns a Set, in which the Set operation can be executed and passed but this method has its limitations that we cannot add new elements to this keyset because it will throw an UnsupportedOperationException.

Due to all these limitations newKeySet() method introduced which returns a Set supported by a given type of ConcurrentHashMap, where the value is Boolean.

How to create ConcurrentHashSet using newKeyset():

Java




// 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");


 
 

This above-mentioned example is not the only way for creating a thread-safe Set in Java.

 

ConcurrentHashSet using keySet(default value):
 

Java




// 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


Java




// 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


 
 

Implementation:

Java




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


Output

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]

These are the methods to create ConcurrentHashSet in Java 8. The JDK 8 API has all the major features like lambda expression and streams along with these small changes which make writing code easy.

The following are some important properties of CopyOnWriteArraySet:

  • It is best suited for very small applications, the number of read-only operations far exceeds variable operations, and it is necessary to prevent interference between threads during traversal.
  • Its thread is safe.
  • Rasters do not support variable delete operations.
  • The traversal through the iterator is fast and does not encounter interference from other threads.
  • The raptors are able to keep a snapshot of the array unchanged when building the iterator.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads