[concurrency-interest] Questions on ConcurrentHashMap

Joe Bowbeer joe.bowbeer at gmail.com
Wed Nov 28 03:15:00 EST 2007

On Nov 27, 2007 10:17 PM, Grace Kwok wrote:
> I am considering replacing my synchronized HashMap cache to be a
> ConcurrentHashMap.
> 1) Consider these operations on a populated map:
> - map.clear() is called
> - immediately or concurrently afterwards map.get(A) and map.get(B) are called.
> We know for sure that if map is a synchronized HashMap, the result of
> A and B would be null.
> However, if map is a concurrentHashMap, the results of get(A) and
> get(B) could be any of the followings [AResult, BResult], [null,
> null], [AResult, null], [null, BResult].  Am I correct?

I agree if "immediately or concurrently" means *after* map.clear() is
called but *before* it completes.

> 2) I have a map cache that behaves as such:
> i) Everytime a request is invoked to get a value corresponding to a
> certain key, the whole map will be populated if it has not been done.
> After which, the map would not change and there would continue to be
> concurrent gets accessing it.
> ii) When the map needs to be invalidated, the whole map would be invalidated.
> iii) After which, we go back to the first step i).
> I am trying to think of the most concurrent and correct way of
> implementing this.
> Below is psuedo code that I thought of:
> static volatile FutureTask<K, V> task = new FutureTask<K, V>(new
> Callable(){...});  where call() method would populate and return a non
> modifiable map.
> private Map<K, V> getMyCache()
> {
>    return task.get();
> }
> public V getValue(K key)
> {
>      getMyCache().get(key);
> }
> public void invalidate()
> {
>     task = new FutureTask<K, V>(new Callable(){...});
> }
> Please comment on the idea as well as suggestion of a better way of doing this.

As David points out, the task is never run.

You could synchronize getMap() and invalidate(), as follows.  Then, if
you need get(A) and get(B) to be in-synch you could implement a
getValues method that would fetch them from the same map -- returned
by getMap.

private Map<K,V> map;

private synchronized Map<K,V> getMap() {
  if (map == null)
    map = createMap();
  return map;

public V getValue(K key) { return getMap().get(key); }

public synchronized void invalidate() { map = null; }

Joe Bowbeer

More information about the Concurrency-interest mailing list