• notice
  • Congratulations on the launch of the Sought Tech site

Java Concurrent HashSet is equivalent to ConcurrentHashMap

I. Overview

In this tutorial, we'll see what is the relative equivalent of creating a thread-safe HashSetcase . Additionally, we will examine the pros and cons of each method.HashSetConcurrentHashMap

2. ConcurrentHashMapThread safety using factory methodsHashSet

First, we'll look at exposing static newKeySet()methods. ConcurrentHashMapBasically, this method returns an instance that respects java.util.Setthe interface and allows the use of standard methods like add(), contains(),etc.

This can simply be created as:

Set<Integer> threadSafeUniqueNumbers = ConcurrentHashMap.newKeySet();

Also, Setthe performance returned is similar HashSet, as both are implemented using hash-based algorithms. Also, the additional overhead from synchronization logic is minimal because the implementation uses ConcurrentHashMap.

Finally, the downside is that this method only exists since Java 8 .

3. ConcurrentHashMapThread safety using instance methodsHashSet

So far, we've seen that ConcurrentHashMap.Next, we'll deal ConcurrentHashMapwith instance methods that can be used to create thread-safe Setinstances. There are two methods available, newKeySet()and newKeySet(defaultValue), which are slightly different from each other.

Both methods create a link to the original mapSet . ConcurrentHashMap, SetIn other words, the value is received every time we send to the original . Also, let's see the difference between these two methods.

3.1 newKeySet()Methods

As mentioned above, the main difference between newKeySet()exposing a map that contains all the keys of the original Set newKeySet(defaultValue)is that the current method does not support Setadding new elements to it. So if we try to call add()or addAll(),we will get UnsupportedOperationException .

Although the operation of the remove(object)or clear()class works as expected, we need to note Setthat any changes on the or class will be reflected in the original map:

ConcurrentHashMap<Integer,String> numbersMap = new ConcurrentHashMap<>();
Set<Integer> numbersSet = numbersMap.keySet();
numbersMap.put(1, "One");
numbersMap.put(2, "Two");
numbersMap.put(3, "Three");
System.out.println("Map before remove: "+ numbersMap);
System.out.println("Set before remove: "+ numbersSet);
System.out.println("Set after remove: "+ numbersSet);
System.out.println("Map after remove: "+ numbersMap);

Next is the output of the above code:

Map before remove: {1=One, 2=Two, 3=Three}
Set before remove: [1, 2, 3]
Set after remove: [1, 3]
Map after remove: {1=One, 3=Three}

3.2. newKeySet(defaultValue)Methods

Let's look at another way of using the keys in the map Setcompared to the one mentioned above, newKeySet(defaultValue)returning an Setinstance that supports setting by calling or on set add()oraddAll()

add()Looking further at the default value passed as a parameter, this is used as the value or addAll()method for each new entry added to the map . The following example shows how it works:

ConcurrentHashMap<Integer,String> numbersMap = new ConcurrentHashMap<>();
Set<Integer> numbersSet = numbersMap.keySet("SET-ENTRY");
numbersMap.put(1, "One");
numbersMap.put(2, "Two");
numbersMap.put(3, "Three");
System.out.println("Map before add: "+ numbersMap);
System.out.println("Set before add: "+ numbersSet);
System.out.println("Map after add: "+ numbersMap);
System.out.println("Set after add: "+ numbersSet);

Here is the output of the above code:

Map before add: {1=One, 2=Two, 3=Three}
Set before add: [1, 2, 3]
Map after add: {1=One, 2=Two, 3=Three, 4=SET-ENTRY, 5=SET-ENTRY}
Set after add: [1, 2, 3, 4, 5]

4. CollectionsThread safety using utility classesHashSet

Let's use the java.util.Collectionsavailable synchronizedSet()methods to create a thread-safe HashSetinstance:

Set<Integer> syncNumbers = Collections.synchronizedSet(new HashSet<>());

Before using this method, we need to realize that it is not as efficient as those discussed above . Basically just wrap the instance into a sync decorator ConcurrentHashMapcompared to implementing a low-level concurrency mechanism .synchronizedSet()Set

5. Use CopyOnWriteArraySetthread safetySet

SetThe last method implemented CopyOnWriteArraySet. Creating Setan instance of this is simple:

Set<Integer> copyOnArraySet = new CopyOnWriteArraySet<>();

Although using this class looks attractive, we need to consider some serious performance drawbacks. Behind the scenes, CopyOnWriteArraySetuse Array,instead of HashMap,to store data. This means that operations like contains()or remove()have O(n) complexity, whereas when using ConcurrentHashMap,Set backed by , the complexity is O(1).

SetUse this implementation when the size is generally kept small and read-only operations are the majority.

6 Conclusion

In this article, we saw the Setdifferent possibilities for creating thread-safe instances and highlighted the differences between them. First we saw ConcurrentHashMap.newKeySet()static methods. HashSet, this should be the first choice . After that we looked at static ConcurrentHashMapmethods andConcurrentHashMapnewKeySet(), newKeySet(defaultValue)

Finally we also discussed Collections. synchronizedSet()and CopyOnWriteArraySetand there are performance drawbacks.


Technical otaku

Sought technology together

Related Topic


Leave a Reply