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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With