1

If we see in the oracle docs of HashSet, it states that while iterating thorough the Set, if we try to manipulate it, it throws ConcurrentModificationException. That is understood.

This is similar to what happens in case of ArrayList or HashMap. But if we see, there are alternate classes provided by Java such as CopyOnWriteArrayList and ConcurrentHashMap.

Why isn't there any such class for HashSet which tackles ConcurrentModificationException? Or even if it exist, please bring it to my notice. I am not aware of such classes

Deca
  • 1,155
  • 1
  • 10
  • 19
  • possible duplicate of [Why there is no ConcurrentHashSet against ConcurrentHashMap](http://stackoverflow.com/questions/6992608/why-there-is-no-concurrenthashset-against-concurrenthashmap) – Andreas Sep 04 '15 at 09:52
  • `CopyOnWriteArrayList` and `ConcurrentHashMap` weren't introduced to prevent CME. They have their own purposes (and CHM was introduced as an upgrade over `Colletions.synchronizedMap()`) – TheLostMind Sep 04 '15 at 09:54

2 Answers2

1

If you want a "ConcurrentHashSet", behaving the same way as a ConcurrentHashMap, you can just use Collections.newSetFromMap() and pass a ConcurrentHashMap as argument.

There are other concurrent Set implementations: ConcurrentSkipListSet, CopyOnWriteArraySet for example.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

TL;DR: A ConcurrentModificationException has nothing to do with threading!

The "concurrent" collections you mention in java.util.concurrent are designed to provide fast and robust alternatives to Collections.synchronizedXXX. They are for use with multiple threads at the same time.

A ConcurrentModificationException, on the other hand, happens when you alter a collection whilst iterating it in the same Thread:

final List<String> list = ...
for(final String s : list) {
    list.remove(s);
}

This code will throw a ConcurrentModificationException on the second iteration every time. Accessing a non-threadsafe Collection from multiple threads at the same time is Undefined Behaviour and may never produce a ConcurrentModificationException. Or it might just catch fire.

In order to avoid such behaviour, use an Iterator and ask it to modify the Collection:

final List<String> list = ...
final Iterator<String> iter = list.iterator();
while(iter.hashNext()) {
    final String s = iter.next();
    iter.remove();
}

To answer your completely unrelated question, in order to create a thread safe Set simply use the following:

final Set<String> threadSafe = Collections.newSetFromMap(new ConcurrentHashMap<>());

With the addition of Collections.newSetFromMap the JDK designers did not see the point in creating a ConcurrentHashSet class.

In summary

Do not use a concurrent Collection to get around the improper use of a Collection in a single threaded environment. It will at best be slower and at worst make your code behave in unexpected ways as the consistency guarantees provided by iterators for concurrent collections are much more relaxed.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166