[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