Vector vs Collections.synchronizedList(ArrayList)

Synchronized collections are a waste of time and dangerous. A trivial example why they are bad is to consider two threads running a loop at the same time on the same collection:

int i = 0;
while (i < list.size())
{
  if (testSomeCondition(list.get())) {
    list.remove(i);
  else
    i++;
}

Our list could be synchronized (e.g. a Vector) and this code would still break horribly. Why? Because the individual calls to size(), get(), remove(), are synchronized but one thread could still be removing items from the list while the other is iterating over it. In other words we have a race condition and the use of synchronized collections has gained us nothing.

To fix the race we have to synchronize the entire operation on the collection or use Java 5 concurrency Locks to do the same.

synchronized (list) {
  int i = 0;
  while (i < list.size())
  {
    if (testSomeCondition(list.get())) {
      list.remove(i);
    else
      i++;
  }
}

This block of code is now thread safe since only one thread can execute the loop at a time. And now there is no reason to use a synchronized collection. We can use an ArrayList instead of a Vector and save ourselves the performance penalty on all those synchronized calls.

So don’t use synchronized collections. If you find yourself having multiple threads hitting the same list then you need to protect the operations on the list, not the individual calls.

Leave a Comment