Why there is no ConcurrentHashSet against ConcurrentHashMap
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
In Java, the ConcurrentHashMap is a popular choice among developers when dealing with multi-threading environments due to its thread-safety features and efficient scalability. On the contrary, there isn't a direct counterpart named ConcurrentHashSet in the Java Collections Framework. Understanding the reason behind this can be quite enlightening for Java developers and enthusiasts alike.
Understanding the Basics: ConcurrentHashMap and HashSet
First, let’s briefly review the purpose and functionality of ConcurrentHashMap and HashSet. The ConcurrentHashMap is a hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates. It handles concurrent modifications gracefully, largely by part-locking its segments, thus allowing concurrent threads to usually operate without interference. This makes it considerably ideal for high-throughput applications.
HashSet, on the other hand, implements the Set interface, backed by a hash table (actually a HashMap instance). It does not allow duplicate entries, and just like HashMap, it is not thread-safe unless externally synchronized.
Why No ConcurrentHashSet?
Interestingly, there is no direct concurrent counterpart to HashSet such as ConcurrentHashSet. The reason lies primarily in Java’s design choice which favors composition over direct extension. In fact, Java provides all functionalities to implement a concurrent set using the existing ConcurrentHashMap.
To create a thread-safe set using ConcurrentHashMap, you can simply back a Set with a ConcurrentHashMap wherein you utilize the keys of the map as the elements of your set. Since the values of the map do not contribute to the characteristics of the set, they can be arbitrary — usually an Object placeholder (like Object()) or Boolean.TRUE is used.
Here’s a simple implementation of a thread-safe set using ConcurrentHashMap:
In the above code, every method of the Set interface is implemented by delegating calls to the corresponding methods of ConcurrentHashMap. This design illustrates the application of composition where ConcurrentHashSet doesn't inherit ConcurrentHashMap but instead manages an instance internally.
Advantages of Using Composition Over Extension
The choice of using composition over extension or direct implementation brings several advantages:
- Flexibility and Loose Coupling: The set functionality is kept separate from the machinery of the hash map, making it easier to modify or replace implementations without affecting the other.
- Reusability: The same
ConcurrentHashMapcan back multiple abstract data types with different behaviors required by various interfaces.
Summarizing Key Points
Here’s a summary table of the discussion:
| Feature | ConcurrentHashMap | ConcurrentHashSet |
| Basis | Hash table | Backed by ConcurrentHashMap |
| Thread Safety | Fully concurrent | Derived from ConcurrentHashMap using composition |
| Duplication | Allows keys | No duplicate entries |
| Direct Extension | NA | Utilizes composition instead of extending ConcurrentHashMap |
Conclusion
Instead of introducing a redundant ConcurrentHashSet, Java provides the tools and paradigms to compose such a collection using ConcurrentHashMap. This approach demonstrates Java’s commitment to object-oriented design principles such as reusability and loose coupling. Using ConcurrentHashMap to create other concurrent collections like ConcurrentHashSet is both straightforward and elegant, giving Java developers powerful tools to handle multi-threaded scenarios effectively.

