Saturday, October 17, 2009

Collections.synchronizedXxx() methods are bad for concurrent scenarios (Java)

The java.util.Collections class provides easy factory methods for collections and maps. In this post, I am trying to highlight why the synchronizedXxx() methods are bad for concurrent scenarios. If you look at the source code of Sun JDK and IBM JDK (I haven't checked Oracle/BEA's) for these methods:


Collections.synchronizedList
Collections.synchronizedSet
Collections.synchronizedMap


you will find they essentially maintain a storage-object-level mutex -- every access obtains a lock upon that mutex to maintain thread-safety before going ahead with the operation. For concurrent scenarios, this is a disaster because you can only invoke one operation at a time.

Fortunately, there are few alternatives you can look at right inside the JDK. For maps, you can use:


java.util.concurrent.ConcurrentHashMap


and for lists or sets, you can look at these:


java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.CopyOnWriteArraySet


Java 6 users can also use these (Note: they are not O(1), but rather O(log(n)) operations):


java.util.concurrent.ConcurrentSkipListMap
java.util.concurrent.ConcurrentSkipListSet


However, there are few points worth knowing:

1. CopyOnWriteXxx collections are suited only for those scenarios where the read operations hugely outnumber the write operations.

2. Concurrent scenarios are better dealt with a strategy at application architecture level rather than brute force use of concurrency-optimized collections.

3. For concurrent scenarios, isolate operations with lifecycle-managed threads each dealing with immutable objects and/or small concurrent datasets rather than giant thread-safe ones. Minimize obtaining of locks rather than making everything thread-safe.

Please let me know what you think.

No comments:

Post a Comment

Disqus for Char Sequence