繁体   English   中英

易失性HashMap与ConcurrentHashMap

[英]Volatile HashMap vs ConcurrentHashMap

我有一个缓存类,其中包含一个用于存储缓存项的volatile HashMap<T>

我很好奇将volatile HashMap更改为ConcurrentHashMap会带来什么后果?

我会获得性能提升吗? 此缓存是只读缓存。

什么是最好的选择? 只是HashMap? 缓存正在一段时间内填充。

首先,您似乎无法理解volatile关键字的作用。 它确保如果声明为volatile的变量保持的引用值发生变化,其他线程将看到它而不是具有缓存副本。 它与访问HashMap线程安全无关

鉴于此,以及你说HashMap是只读的事实......你当然不需要使用提供线程安全的任何东西,包括ConcurrentHashMap

编辑添加:您现在的最后一次编辑说“缓存正在按间隔填充”

那不是只读的,不是吗?

如果你想有螺纹,而你正在编写从中读取(更新现有的HashMap),那么你应该使用ConcurrentHashMap ,是的。

如果要填充全新的HashMap然后将其分配给现有变量,则使用volatile

你说缓存是只读的,但也会在一个似乎相互矛盾的时间间隔内更新。

如果整个缓存在一个时间间隔内更新,我将继续使用volatile。 volatile将确保更新的地图安全发布。

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);
   }
}

如果间隔更新正在修改相同的缓存,那么您可能希望使用ConcurrentHashMap,或复制映射,更新副本并更新引用。

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);
   }
}

我的Web应用程序有一个类似的用例。 我正在使用HAshMap进行内存缓存。 用例如下 -

  1. 一个用户请求进入并首先使用输入密钥检查缓存是否存在记录。 这是在add方法中完成的。
  2. 如果该对象不存在,则将新记录插入缓存中。
  3. 类似地,在remove方法中,首先使用密钥检查缓存中是否存在记录,如果找到则只删除它。

我想确保两个线程同时在add上执行一个而另一个在remove方法上,这种方法会确保他们在他们看到缓存中的最新数据吗? 如果我没有错,那么同步方法负责线程安全,因为volatile负责可见性。

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);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM