When you use Collections.synchronizedList(new ArrayList<>())
you are separating the two implementation details. It’s clear, how you could change the underlying storage model from “array based” to, e.g. “linked nodes”, by simply replacing new ArrayList
with new LinkedList
without changing the synchronized
decoration.
The statement that Vector
“will be slightly faster” seems to be based on the fact that its use does not bear a delegation between the wrapper and the underlying storage, but deriving statements about the performance from that was even questionable by the time, when ArrayList
and the synchronizedList
wrapper were introduced.
It should be noted that when you are really concerned about the performance of a list accessed by multiple threads, you will use neither of these two alternatives. The idea of making a storage thread safe by making all access methods synchronized
is flawed right from the start. Every operation that involves multiple access to the list, e.g. simple constructs like if(!list.contains(o)) list.add(o);
or iterating over the list or even a simple Collections.swap(list, i, j);
require additional manual synchronization to work correctly in a multi-threaded setup.
If you think it over, you will realize that most operations of a real life application consist of multiple access and therefore will require careful manual locking and the fact that every low level access method synchronizes additionally can not only take away performance, it’s also a disguise pretending a safety that isn’t there.