3

If I create such a list:

List<MyObj> myobjs = Collections.synchronizedList(new ArrayList<MyObj>()); 

the associated documentation claims that this returned list needs to be synchronized in order to iterate over the elements. Yet, I can synchronize a regular List and protect it with a synchronized block. So, why do I need a "synchronizedList"?

Returns a synchronized (thread-safe) list backed by the specified list. In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.

It is imperative that the user manually synchronize on the returned list when iterating over it:

  List list = Collections.synchronizedList(new ArrayList());
      ...
  synchronized (list) {
      Iterator i = list.iterator(); // Must be in synchronized block
      while (i.hasNext())
          foo(i.next());
  }

Failure to follow this advice may result in non-deterministic behavior. The returned list will be serializable if the specified list is serializable.

Parameters: list the list to be "wrapped" in a synchronized list. Returns: a synchronized view of the specified list.

paiego
  • 3,619
  • 34
  • 43
  • 1
    It has already been answered here: http://stackoverflow.com/questions/9468187/collections-synchronizedlist-and-synchronized. Simple operations are guaranteed to be thread safe, but iterating is not a simple opration. – Jean-Baptiste Yunès Feb 06 '15 at 20:02
  • I agree that the questions are similar, but not exact duplicates. i.e. I asked what is the purpose of the SynchronizedList if you also need to synchronize, and romsky asked what is the purpose of synchronize when using SynchronizedList. – paiego Feb 06 '15 at 20:14
  • Because it can only be synchronized for simple operations... How would you do it? – Jean-Baptiste Yunès Feb 06 '15 at 20:18

1 Answers1

3

The synchronizedList is a convenience wrapper that allows you to avoid manual synchronization in most cases, but not when iterating over it.

With a normal unsynchronized list, you would need to always manually synchronize if it is used by multiple threads, thus it can be handy to use synchronizedList.

A case where a synchronizedList are necessary might be if you pass a list to some third-party code that does not synchronize on the list, but you still need synchronization. However, this is quite error-prone as you would rely on the fact that the third-party code does not iterate over the list or use other non-atomic operations, thus it would be best to avoid this altogether if possible (for example, by copying the list).

Philipp Wendler
  • 11,184
  • 7
  • 52
  • 87
  • 1
    Thanks... From romski's post, "Also Important to note that any methods that use Iterators for example Collections.sort() will also need to be encapsulated inside a synchronized block." – paiego Feb 06 '15 at 20:15