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
It’s worth to have a look at the documentation of Collections.synchronizedCollection rather than Collections.synchronizedSet()
as that documentation has been cleaned up already:
It is imperative that the user manually synchronize on the returned collection when traversing it via
Iterator
,Spliterator
orStream
: …
I think, this makes it pretty clear that there is a distinction between the iteration via an object other than the synchronized Collection
itself and using its forEach
method. But even with the old wording you can draw the conclusion that there is such a distinction:
It is imperative that the user manually synchronize on the returned set when iterating over it:…
(emphasis by me)
Compare to the documentation for Iterable.forEach:
Performs the given action for each element of the
Iterable
until all elements have been processed or the action throws an exception.
While it is clear to the developer that there must be an (internal) iteration happening to achieve this, this iteration is an implementation detail. From the given specification’s wording it’s just a (meta-)action for performing an action to each element.
When using that method, the user is not iterating over the elements and hence not responsible for the synchronization mentioned in the Collections.synchronized…
documentation.
However, that’s a bit subtle and it’s good that the documentation of synchronizedCollection lists the cases for manual synchronization explicitly and I think the documentation of the other methods should be adapted as well.