并发集合的包含方法是无用的吗?

if(concurrentHashMap.containKey(key)) { // oops, v has been removed in another thread right after current thread // complete containKey calling Value v = concurrentHashMap.get(key); // do something on v // null pointer exception } 

似乎并发集合的包含类方法是无用的,以解决上述问题:

 Vaule v = concurrentHashMap.get(key); if(v != null) { // ok, hold v's reference // do something on v } 

我对吗?

正如注释线程中所述:不, containsKey不会以任何方式锁定条目,因此稍后调用get(key)可能会返回null 。 也就是说,如果你只对布尔值感兴趣 – 是地图中的关键吗? – 之后您不需要获取密钥,然后containsKey就可以了。

另外, Map接口需要containsKey ,所以它不像它不会在那里。

这不是无用的。 想象一下, get的结果不需要做任何事情。 在这种情况下, containsKeyget (并遭受)相同的问题。

然而,正如Voo在评论中指出的那样,代码通常可以用putIfAbsent (用于表示更大的primefaces操作)来编写。

它只是没有 (因为它本身不能)创建更大的primefaces上下文 。 也就是说,没有什么能阻止其他线程在containsKeyget之间对concurrentHashMap进行操作。 密切关注javadoc的合同 :

…即使所有[个别]操作都是线程安全的,检索操作也不需要锁定,并且没有任何支持以阻止所有访问的方式锁定整个表

检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠。 检索[例如containsKey或get]反映了最近完成的更新操作的结果 ……

对象是“线程安全的”并且在并发上下文中正确使用所述对象之间存在差异。

快乐的编码。