code: public static <T> List<T> synchronizedList(List<T> list) {
          return (list instanceof RandomAccess ?
                  new SynchronizedRandomAccessList<>(list) :
                  new SynchronizedList<>(list));
      }
docs: Returns a synchronized (thread-safe) list backed by the specified
  list.  In order to guarantee serial access, it is critical that
  <strong>all</strong> access to the backing list is accomplished
  through the returned list.<p>
  
  It is imperative that the user manually synchronize on the returned
  list when iterating over it:
  <pre>
  List list = Collections.synchronizedList(new ArrayList());
  ...
  synchronized (list) {
  Iterator i = list.iterator(); // Must be in synchronized block
  while (i.hasNext())
  foo(i.next());
  }
  </pre>
  Failure to follow this advice may result in non-deterministic behavior.
  
  <p>The returned list will be serializable if the specified list is
  serializable.
  
  @param  <T> the class of the objects in the list
  @param  list the list to be "wrapped" in a synchronized list.
  @return a synchronized view of the specified list.