- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
How to Create a Thread-Safe ConcurrentHashSet in Java?
In this article, we will see what are the possibilities available to create thread-safe HashSet instances and see what will be equivalent to ConcurrentHashMap for HashSet. We will also look at the benefits and drawbacks of each approach.
Before JDK8 we are not able to create a Thread Safe ConcurrentHashMap because java.util.concurrent package in JDK8 does not provide a class named ConcurrentHashSet, two new methods were added that are discussed below. ConcurrentHashMap is the Map implementation that allows us to modify the Map while iterating. The ConcurrentHashMap operations are thread-safe. ConcurrentHashMap doesn't allow null for keys and values.
Ways to Create Thread-safe ConcurrentHashSet
When Coming to ConcurrentHashSet can be created by utilizing ConcurrentHashMap, which enables the use of keySet(default Value) and newKeySet() methods to obtain a proper Set. This provides access to functions such as contains(), remove(), and more.
keySet (Default Value)
newKeySet()
Creating ConcurrentHashSet Using KeySet(default Value)
The keySet(default Value) method of the ConcurrentHashMap class provides a Set view of the keys stored in the map. The set is supported by the map itself, meaning that modifications to the map will be reflected in the set, and vice versa.
Syntax
public ConcurrentHashMap.KeySetView<K,V> keySet(default_value)
Parameter
Passing default_value while creating a set using ConcurrentHashMap
Example
//A Java program to demonstrate the implementation of a ConcurrentHashSet that ensures thread safety. import java.io.*; import java.util.*; public class TutorialsPoint { public static void main (String[] args) { ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>(); map.put("Tutorials",1); map.put("Point",2); map.put("Java", 3); map.put("article on",4); map.put("Threads", 5); //Create a Set using concurrenthashmap Set intialSet = map.keySet(120); //The value 120 is an arbitrary default value System.out.println("Initial set: " + intialSet); // The value will remain unchanged as 120 // but no error will be encountered. intialSet.add("Element"); System.out.println("After removing an element " + intialSet); //Checking if the set contains if yes we will remove and print the set if(intialSet.contains("Threads")) { intialSet.remove("Threads"); System.out.println("After removing an element " + intialSet); } } }
Output
Initial set: [Threads, Java, Tutorials, Point, article on] After removing an element [Threads, Java, Tutorials, Element, Point, article on] After removing an element [Java, Tutorials, Element, Point, article on]
Drawback
While trying to add a new element to the set the value will remain the same i.e the value that we have set as default while creating a set.
Due to all the limitations that we are facing above that’s why they introduced the newKeySet() method that returns a Set that is backed by a ConcurrentHashMap, where the values associated with the keys are of type Boolean.
How to Create ConcurrentHashSet Using NewKeySet()
The newKeySet() method belongs to the ConcurrentHashMap class which generates a new set supported by a ConcurrentHashMap, with elements of the specified type mapped to Boolean.TRUE.
Syntax
public static <K> ConcurrentHashMap.KeySetView<K,Boolean> newKeySet()
Code that is present below will give us an idea how to create a ConcurrentHashSet using newKeySet(). To resolve all the issues that we face in the 1st approach we will now use newkeySet().
Example
// A Java program to demonstrate the implementation of a ConcurrentHashSet that ensures thread safety. import java.io.*; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public class TutorialsPoint { public static void main (String[] args) { // Creating a map ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>(); map.put("Tutorials",1); map.put("Point",2); map.put("Java", 3); map.put("article on",4); map.put("Threads", 5); Set <String> subjectsSet = ConcurrentHashMap.newKeySet(); subjectsSet.add("Computer Networks"); subjectsSet.add("DBMS"); subjectsSet.add("OS"); // displaying the values of set System.out.println("before adding an element into subjects set: " + subjectsSet); //use add() method to insert elements into the set subjectsSet.add("DSA"); // Print the set again to verify the changes System.out.println("after adding an element into subjects set: " + subjectsSet); // we can use utilize contains() method to check presence of an element in a set if(subjectsSet.contains("DSA")) System.out.println("Yes it is there"); else System.out.println("No it is not there"); // we can do it directly like this :subjectsSet.contains("DSA")); it returns boolean value // To remove an element from a set use remove() method subjectsSet.remove("OS"); System.out.println("after removing an element from subjects set: " + subjectsSet); } }
Output
before adding an element into subjects set: [Computer Networks, OS, DBMS] after adding an element into subjects set: [Computer Networks, DSA, OS, DBMS] Yes it is there after removing an element from subjects set: [Computer Networks, DSA, DBMS]
We have other ways also to create thread-safe HashSet but not used mostly and also less efficient than the ones which we discussed above.
ConcurrentHashSet Using Collections Utility Class
The synchronizedSet() method which belongs to Java Collections class is employed to obtain a synchronized (thread-safe) set, which is supported by the specified set.
In this method, we utilize the synchronizedSet() method provided by java.util.Collections to create a HashSet instance that is thread-safe.
Syntax
public static <T> Set<T> synchronizedSet(Set<T> s)
Parameter
This set is encapsulated within a synchronized set.
Example
import java.io.*; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.Collections; import java.util.HashSet; public class TutorialsPoint { public static void main (String[] args) { Set<String> names= new HashSet<String>(); //let’s Add values to the set using add() names.add("Hari"); names.add("Revanth"); names.add("Lokesh"); names.add("Kiran"); //Creating a synchronized set Set<String> synchronizedSet = Collections.synchronizedSet(names); System.out.println("Synchronized set is :"+synchronizedSet ); } }
Output
Synchronized set is :[Revanth, Hari, Kiran, Lokesh]
It is less efficient than the ones that are discussed above. Basically synchronizedSet() wraps Set into synchronized decorator when compared with ConcurrentHashMap that implements a low-level concurrency mechanism.
Thread Safe Set Using CopyOnWriteArraySet
The last approach that is used to create thread-safe implementations is CopyOnWriteArraySet. Below is the code snippet for creating an instance of Set.
Example
Set<String> copyOnArraySet = new CopyOnWriteArraySet<>(); copyOnArraySet.add("sample");
The following are the some important properties and the drawbacks that we need to consider −
It uses an array not a HashMap to store the data which means the operations like contains() or remove() have O(n) complexity when compared to ConcurrentHashMap that takes O(1).
It is suited for very small applications and we need to prevent interference between the threads during traversal.
Rasters do not provide operations to erase variables.
Conclusion
In this article we have seen various possibilities to create thread-safe Set instances. Initially, we explored the creation of a ConcurrentHashSet in Java, which is backed by ConcurrentHashMap. and the differences between those methods and this should be the first choice when a thread-safe hash set is needed.
Finally we also discussed synchronizedSet(),CopyOnWriteArraySet approaches and their performance drawbacks.