As we know, iterating over a concurrent collection is not thread safe by default, so one cannot use:
Set set = Collections.synchronizedSet(new HashSet&l
As @Holger said, the doc clearly says user must manually synchronize collections returned by Collections.synchronizedXyz()
when tranversing it via Iterator
:
It is imperative that the user manually synchronize on the returned collection when traversing it via Iterator, Spliterator or Stream:
Collection c = Collections.synchronizedCollection(myCollection); ... synchronized (c) { Iterator i = c.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }
I want to explain a bit more about code.
Consider Collections.synchronizedList() method. It returns Collections.SynchronizedList class instance, which extends SynchronizedCollection which defines iterator() as follows:
public Iterator iterator() {
return c.iterator(); // Must be manually synched by user!
}
Compare this with other methods of SynchronizedCollections
, for example:
public String toString() {
synchronized (mutex) {return c.toString();}
}
Thus SynchronizedList
inherits iterator()
from SynchronizedCollection
, which needs to be synched manually by user.