I decided to delve a bit into the source code and noticed that Collections.synchronizedList(List) implemented as follows:
public static <T> List<T> synchronizedList(List<T> list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<T>(list) : new SynchronizedList<T>(list)); }
where the SynchronizedList nested class:
static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> { private static final long serialVersionUID = -7754090372962971524L; final List<E> list; SynchronizedList(List<E> list) { super(list); this.list = list; } SynchronizedList(List<E> list, Object mutex) { super(list, mutex); this.list = list; } public boolean More ...equals(Object o) { synchronized(mutex) {return list.equals(o);} }
As you can see, the class uses a private lock object to ensure thread safety. But the documentation allows us to iterate over it, using the lock on the objetct object returned by the factory method.
It is imperative that the user manually synchronizes the list when it repeats:
So, we use different locks to iterate and change the list ( add , remove , etc.).
Why is it considered safe?
source share