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

jea*_*ean 3 java concurrency

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
}
Run Code Online (Sandbox Code Playgroud)

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

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

我对吗?

小智 5

这没用.想象一下,结果不需要做任何事情get.在这种情况下,无论是containsKeyget有(和患)相同的问题.

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

不会(因为它本身不能)创建更大的原子上下文.也就是说,没有什么阻止其他线程做的东西concurrentHashMap之间containsKeyget.密切关注javadoc合同:

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

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

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

快乐的编码.