java - ConcurrentHashMap put 与 putIfAbsent

标签 java caching concurrency hashmap

Java Docs也就是说,putIfAbsent 等同于

   if (!map.containsKey(key)) 
      return map.put(key, value);
   else
      return map.get(key);

因此,如果键存在于映射中,则它不会更新其值。这是正确的吗?

如果我想根据某些条件更新键值怎么办?说下过期时间等

这会是添加和更新缓存的更好实现吗?

public void AddToCache(T key, V value)
{
   V local = _cache.putifabsent(key, value);

   if(local.equals(value) && local.IsExpired() == false){
     return;
   }
   // this is for updating the cache with a new value
   _cache.put(key, value);
}

最佳答案

So it doesnt update a key's value. is this correct?

没错。它将返回 map 中已有的当前值。

would this be a better impl for adding and updating cache?

有几件事可以让您的实现变得更好。

1. 你不应该使用 putIfAbsent 来测试它是否存在,你应该只在你想确保它不存在时才使用它 putIfAbsent。相反,您应该使用 map.get 来测试它是否存在(或 map.contains)。

    V local = _cache.get(key);
    if (local.equals(value) && !local.IsExpired()) {
        return;
    }

2. 而不是 put 你会想要替换,这是因为竞争条件可能会发生,其中 if 可以被两个或多个线程评估为 false两个(或更多)线程中的哪一个将覆盖另一个线程的放置。

你可以做的是 replace

归根结底,它可能看起来像这样

public void AddToCache(T key, V value) {
    for (;;) {

        V local = _cache.get(key);
        if(local == null){
            local = _cache.putIfAbsent(key, value);
            if(local == null)
                return;
        }
        if (local.equals(value) && !local.IsExpired()) {
            return;
        }

        if (_cache.replace(key, local, value))
            return;
    }
}

关于java - ConcurrentHashMap put 与 putIfAbsent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10486413/

相关文章:

caching - HTML5 应用程序 list 移动支持

.net - ConcurrentDictionary 的列表顺序是否得到保证?

java - 如何将 JComponent 定位到 BorderLayout 中的真正中心?

android - 有没有人成功地限制了他们的 WebView 缓存的大小?

java - 为什么 Hibernate 包含带有插入的标识字段?

javascript - 如何阻止 Firefox 在本地主机上缓存文本区域的内容?

java - LockManager - 想法和API

java - 从 ThreadPoolExecutor 获取正在运行和排队的任务?

java - 程序未读取第一个字符串输入

java - 正则表达式捕获组未按预期工作