[concurrency-interest] ConcurrentReaderHashMap kudos!

nnn6-twfe@spamex.com nnn6-twfe@spamex.com
Sat, 04 Dec 2004 19:42:37 -0500

Recently, I have successfully incorporated ConcurrentReaderHashMap in a 
large enterprise software which has a J2EE web portal user interface.

The problem
We have lots of data which is cached inside the J2EE server for
performance reasons. (Other data is loaded directly from database on
demand.)  The data cache can have many reader threads accessing the data
and only rarely will there be a writer thread updating the data, something
like 99.999% of the access is read only. The majority of the readers
threads are accessing the data to construct HTML pages.

Before using concurrent libraries, we were using the standard 1.4 java
collection classes like Hashtable, Vector, etc. plus some of our methods
needed to be synchronized, e.g. when the data structure is an aggregate
like a hash of a hash. This worked fine as far as data integrity, but the
reader threads would get bit by those ConcurrentModificationExceptions (
CCMEs) it they were iterating when an update happened at the same time.

Solution before ConcurrentReaderHashMap
We either had to synchronize the readers with the writers, or catch the
ConcurrentModificationExceptions when they happen and just repeat the
operation.  Since we wanted to have maximum performance and minimum
contention between the pool of reader threads,  we opted to just repeat
the operation when the CCMEs happened.

We have changed many of the data structures to use ConcurrentReaderHashMap
(1.3.4 version because we aren't on JDK 1.5) instead of Hashtable.  After
running tests we didn't notice any performance impact from the switch.  We
removed all the exception handling for CCMEs, and then performed a stress
test on our application where we have several writer threads making
nonstop modifications in the cache while many reader threads are accessing
it, and all those CCMEs were gone.  Our code is now simplified because we
don't have that restart logic in there to handle the CCMEs.

So far, the ConcurrentReaderHashMap is the ideal data structure for our
usage scenario of many readers and occassional writers.

I would really like to have a ConcurrentReaderSortedMap and/or
ConcurrentReaderSortedSet.  Some of our cache data structures need to
maintain the most commmon sort order for performance reasons.  It really
improves performance to maintain the data in sorted order in our case
because there are 10000 readers for every writer, and most of the readers
need the data in the same sorted order.  Currently we are using
Collections.synchronizedSortedMap(new TreeMap())  or Collections.
synchronizedSortedSet(new TreeSet()).  We have thought about using a
ConcurrentReaderHashMap as the main data structure and then have different
sorted views of the data, but we are uneasy about possible synchronization
issues between the two.