The easiest way to get a synchronized version of a java.util.Set would be using Collections.synchronizedSet() like this:
Set mySyncSet = Collections.synchronizedSet(new HashSet());
The Java API says about this new object that:
It is imperative that the user manually synchronize on the returned set when iterating over it
My question is, if I create a copy of this Set using a copy constructor like this:
Set mySetCopy = new HashMap(mySyncSet);
Wil it be thread-safe? (isn't HashMap constructor using iteration to get members of Set after all?) or should I manually synchronize the operation like this?:
Set mySetCopy;
synchronized(mySyncSet) {
mySetCopy = new HashMap(mySyncSet);
}
Lets take a look at the code:
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
So that just calls addAll
,
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
So this loops over the Collection
you give it.
The answer is therefore no, constructor copy is not thread safe.
You need to use your second option and do a explicit synchronized
on the Set
before passing it into the constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With