Volatile HashMap vs ConcurrentHashMap

浪子不回头ぞ 提交于 2019-12-20 08:43:46

问题


I have a cache class which contains a volatile HashMap<T> to store cache items.

I'm curious what would be the consequences of changing volatile HashMap to ConcurrentHashMap?

Would i gain performance increase? This cache is readonly cache.

What would be the best option to use? just HashMap? Cache is being populated on a interval.


回答1:


First, it appears you don't understand what the volatile keyword does. It makes sure that if the reference value held by the variable declared volatile changes, other threads will see it rather than having a cached copy. It has nothing to do with thread-safety in regard to accessing the HashMap

Given that, and the fact that you say the HashMap is read-only ... you certainly don't need to use anything that provides thread-safety including a ConcurrentHashMap

Edit to add: Your last edit you now say "The cache is being populated on a interval"

That's not read-only then, is it?

If you're going to have threads reading from it while you are writing (updating the existing HashMap) then you should use a ConcurrentHashMap, yes.

If you are populating an entirely new HashMap then assigning it to the existing variable, then you use volatile




回答2:


You say the cache is read-only, but also being updated on an interval which seems contradictory.

If the whole cache gets updated on an interval, I'd keep using the volatile. The volatile will make sure that the updated map is safely published.

public final class  Cache
{
   private volatile Map<?,?> cache;

   private void mapUpdate() {
      Map<?,?> newCache = new HashMap<>();

      // populate the map

      // update the reference with an immutable collection
      cache = Collections.unmodifiableMap(newCache);
   }
}

If the interval update is modifying the same cache, then you probably want to use a ConcurrentHashMap, or copy the map, update the copy, and update the reference.

public final class  Cache
{
   private volatile Map<?,?> cache;

   private void mapUpdate() {
      Map<?,?> newCache = new HashMap<>(cache);

      // update the map

      // update the reference with an immutable collection
      cache = Collections.unmodifiableMap(newCache);
   }
}



回答3:


I have a similar use case for my web application. I am using a HAshMap for my in-memory cache. The use case is as follows -

  1. One user request comes in and first checks the cache for existence of a record using an input key. This is done in the add method.
  2. If the object is not present then it inserts the new record in the cache.
  3. Similarly in the remove method first checks the presence of a record in the cache using the key and if found just removes that.

I want to make sure of two threads are concurrently executing one on add and another on remove method will this approach make sure they at point of them they see the latest data in the cache? If i am not wrong then synchronized method takes care of thread safety where as volatile takes care of visibility.

private volatile HashMap<String,String> activeRequests = new HashMap<String,String>();
public synchronized boolean add(String pageKey, String space, String pageName) {
    if (!(activeRequests.get(pageKey) == null)) {
       return false;
    }
    activeRequests.put(pageKey, space + ":" + pageName);
    return true;
}

public synchronized void remove(String pageKey) {       
    if(!(activeRequests.get(pageKey) == null))
        activeRequests.remove(pageKey);
    }


来源:https://stackoverflow.com/questions/10357823/volatile-hashmap-vs-concurrenthashmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!