Thursday, December 26, 2013

Synchronized access to a List and other Java Collections

Java 1.2 collections are not sychronized for faster performance but are not thread safe in a multithreaded environment.  These collections can be synchronized using Collections.synchronizedXxx() methods.

The Java Collections class has several static methods that return synchronized (thread-safe)  collections. These methods are:

Collections.synchronizedCollection(Collection<T> c)
Collections.synchronizedList(List<T> list)
Collections.synchronizedMap(Map<K,V> m)
Collections.synchronizedSet(Set<T> s)
Collections.synchronizedSortedMap(SortedMap<K,V> m)
Collections.synchronizedSortedSet(SortedSet<T> s

See the javadoc for the Collections class.

Example:

package com.example;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class SynchronizedExample {

 public static void main(String[] args) {

  List<String> syncList = Collections.synchronizedList(new ArrayList<String>());

  syncList.add("mango");
  syncList.add("orange");
  syncList.add("apple");

  // manually synchronize on the returned synchronized list 'syncList' (using 'synchronized') when iterating over it
  // failure to use a 'synchronized' block may result in non-deterministic behavior
  synchronized (syncList) {
   Iterator<String> iterator = syncList.iterator();
   while (iterator.hasNext()) {
    System.out.println("fruit: " + iterator.next());
   }
  }

 }

} 

It is imperative to manually synchronize on 'syncList' (the list returned by Collections.synchronizedList) by using a synchronized block when iterating over it to lock the synchronized List object.