ConcurrentMap.putIfAbsent()中提到的先前值是什么

时间:2015-09-30 12:28:13

标签: java java.util.concurrent concurrenthashmap

ConcurrentMap指定putIfAbsent()的返回值为:

  

与指定键关联的先前值,如果没有键的映射,则返回null。 (如果实现支持空值,则null返回还可以指示映射先前将null与键关联。)

并提供以下代码作为示例。

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

问题是,如果只有在给定密钥的地图中不存在条目时才调用map.put(key, value),那么如何才能存在先前的值?在我看来,如果在调用putIfAbsent()之前没有包含给定键的条目,它将始终返回当前值或null。

3 个答案:

答案 0 :(得分:3)

请考虑以下几行:

ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
System.out.println(map.putIfAbsent("key", "value1")); // prints null (no previous value)
System.out.println(map.putIfAbsent("key", "value2")); // prints "value1"

在第一次调用putIfAbsent时,没有与关键字key相关联的值。因此,putIfAbsent将返回null

在第二次调用时,putIfAbsent将返回上一个映射,即value1,并且该值不会在地图中更新,因为它已经存在。

虽然putIfAbsent确实会返回当前值(如果有该键的映射),但此处引入“先前值”的概念与Map.put的定义一致,返回先前的值。引用它的Javadoc:

  

与key关联的上一个值,如果没有key的映射,则返回null。

答案 1 :(得分:2)

我认为此前的单词只是为了强调该值在调用之前已经在地图中。它并不是一个很好的选择,因为它表明地图中可能存在一个与前一个不同的新值,而实际上并不存在。但是代码示例完全解释了该方法的作用,因此我不担心它。

答案 2 :(得分:0)

如果我们讨论任何并发数据结构,我们需要记住,这些数据结构是为并发执行而设计的。

putIfAbsent表示如果Thread1Thread2尝试使用相同的key添加一些数据,只有一个Thread会执行此操作。