2

I'm reading the java official doc regarding wrappers implementation, which are static methods in Collections used to get synchronized collection, for example : List<Type> list = Collections.synchronizedList(new ArrayList<Type>()); ...
the thing that I did not understand is the following (I quote from the java doc ) :

A collection created in this fashion is every bit as thread-safe as a normally synchronized collection, such as a Vector. In the face of concurrent access, it is imperative that the user manually synchronize on the returned collection when iterating over it. The reason is that iteration is accomplished via multiple calls into the collection, which must be composed into a single atomic operation...

how it could be every bit as thread-safe an need to manually synchronize when iterating ??

Cœur
  • 37,241
  • 25
  • 195
  • 267
aName
  • 2,751
  • 3
  • 32
  • 61
  • 1
    This means you also have to manually synchronize on the returned collection when iterating over a normally synchronized collection, such as a Vector. – Peter Bagyinszki Mar 26 '18 at 11:06

2 Answers2

4

It is thread safe in the sense that each of it's individual methods are thread safe, but if you perform compound actions on the collection, then your code is at risk of concurrency issues.

ex:

List<String> synchronizedList = Collections.synchronizedList(someList);
synchronizedList.add(whatever); // this is thread safe

the individual method add() is thread safe but if i perform the following:

List<String> synchronizedList = Collections.synchronizedList(someList);
if(!synchronizedList.contains(whatever))
       synchronizedList.add(whatever); // this is not thread safe

the if-then-add operation is not thread safe because some other thread might have added whatever to the list after contains() check.

Ramanlfc
  • 8,283
  • 1
  • 18
  • 24
  • The not-thread-safe-problem even appears if you only iterate over the items of `synchronizedList` via e.g. `for(String s : synchronizedList) {System.out.prin(s);}`. During iteration another thread could edit the list -> ConcurrentModificationException – mrbela Jun 26 '19 at 14:30
1

There is no contradiction here: collections returned from synchronizedXyz suffer the same shortcoming as synchronized collections available to you directly, namely the need to manually synchronize on iterating the collection.

The problem of external iteration cannot be solved by a better class design, because iterating a collection inherently requires making multiple calls to its methods (see this Q&A for detailed explanation).

Note that starting with Java 1.8 you can iterate without additional synchronization using forEach method of your synchronized collection*. This is thread-safe, and comes with additional benefits; see this Q&A for details.

The reason this is different from iterating externally is that forEach implementation inside the collection takes care of synchronizing the iteration for you.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523