Friday, 22 April 2016

What mechanism is used in synchronized collection classes and what problems can be occurred ?


Classes like Vector, Hashtable and Wrappers created by Collections.synchronizedXxx achieves thread safety by synchronizing every public method so that only one thread at a time can access the collection state.

Problems
a. Malfunction in compound actions
Synchronized collections are technically thread-safe but sometimes, additional client side locking needed to guard operations like :
  1. Iteration
  2. Navigation
  3. Condition : put-if-absent

Example
public static Object getLast(Vector list) {
  int lastIndex = list.size() - 1;
  return list.get(lastIndex);
}
public static void deleteLast(Vector list) {
  int lastIndex = list.size() - 1;
  list.remove(lastIndex);
}

If thread A calls getLast on a Vector with 10 elements, thread B calls deleteLast on the same Vector, and the operations are interleaved so getLast throws ArrayIndexOutOfBoundsException.

Solution
Client side locking keeping the lock of collection using synchronized block in both above methods. Although, it will have some additional scalability cost.

Example 
public static Object getLast(Vector list) {
  synchronized (list) {
    int lastIndex = list.size() - 1;
    return list.get(lastIndex);
  }
}


b. Fail-Fast : cannot deal with Concurrent modification
The iterators returned by the synchronized collections cannot deal with concurrent modification as they are fail-fast means they throw the unchecked ConcurrentModificationException when they detect the collection has changed since iteration began.

The methods like containsAll, removeAll, retainAll and constructors taking collections as argument may indirectly iterate the collection and may throw ConcurrentModificationException.

Solution #1
During iteration, clone the collection and iterate the copy instead so that no other thread can modify it during iteration, eliminating the possibility of ConcurrentModificationException.
Although, cloning has a performance cost.

Solution #2
Use locking everywhere a shared collection might be iterated.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.