Is a sync grid copy constructor safe?

The easiest way to get a synchronized version of java.util.Set would be using Collections.synchronizedSet () as follows:

Set mySyncSet = Collections.synchronizedSet(new HashSet()); 

The Java API talks about this new object, which:

It is imperative that the user manually synchronizes the returned set when iterating over it

My question is: if I create a copy of this Install using the copy constructor as follows:

 Set mySetCopy = new HashMap(mySyncSet); 

Kill it thread safe? (is not a HashMap constructor using iteration to get Install members?) or do I need to manually synchronize the operation as follows:

 Set mySetCopy; synchronized(mySyncSet) { mySetCopy = new HashMap(mySyncSet); } 
+4
source share
2 answers

Let's look at the code:

 public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } 

To just call addAll ,

 public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } 

So this happens through the Collection that you give it.

Therefore, the answer is no, the constructor copy is not thread safe.

You need to use the second option and make explicit synchronized on Set , before passing it to the constructor.

+9
source

The second method is preferable. If any thread modifies the original thread while that thread iterates through your collection to copy the links to your new collection, you will have problems.

All code that accesses or modifies the collection must manually synchronize to the same instance ... as pointed out by JavaDoc.

0
source

Source: https://habr.com/ru/post/1491130/


All Articles