java.util.concurrent.ConcurrentHashMap.putIfAbsent是否需要位于同步块中?

java.util.concurrent.ConcurrentHashMap.putIfAbsent是否需要位于同步块中?,java,multithreading,concurrency,synchronization,concurrenthashmap,Java,Multithreading,Concurrency,Synchronization,Concurrenthashmap,我正在努力追踪比赛情况,所有迹象似乎都指向ConcurrentHashMap.putIfAbsent()。如果两个线程使用同一个键在空映射上调用putIfAbsent(),两个线程都可以进行查找以查看该键是否还不存在,那么两个线程是否都可以尝试添加该键?由于某种原因,当我第一次开始使用putIfAbsent()时,我认为调用不需要同步。但现在我看不出,如果时间安排正确,它将如何阻止两个线程添加它们的值。我无法在生产之外复制这个 谢谢任何并发集合的操作都不需要使用synchronized 这是出于

我正在努力追踪比赛情况,所有迹象似乎都指向
ConcurrentHashMap.putIfAbsent()
。如果两个线程使用同一个键在空映射上调用
putIfAbsent()
,两个线程都可以进行查找以查看该键是否还不存在,那么两个线程是否都可以尝试添加该键?由于某种原因,当我第一次开始使用
putIfAbsent()
时,我认为调用不需要同步。但现在我看不出,如果时间安排正确,它将如何阻止两个线程添加它们的值。我无法在生产之外复制这个


谢谢

任何并发集合的操作都不需要使用synchronized

这是出于设计,实际上锁定集合对其他操作没有影响。(除非它们也被锁定)在这种情况下,会使它们变慢

如果两个线程使用同一个键在空映射上调用putIfAbsent(),两个线程都可以进行查找以查看该键不存在,那么两个线程是否都可以尝试添加该键

两者都可以尝试,但只有一个会成功。两个线程看起来不可能成功

由于某种原因,当我第一次开始使用putIfAbsent()时,我认为调用不需要同步

没有

但现在我看不出,如果时间安排正确,它将如何阻止两个线程添加它们的值

它在代码中执行一个操作,这意味着只有一个操作可以成功,线程将知道哪个操作成功。CAS操作不需要锁定,因为它使用底层汇编指令来执行此操作。事实上,您通常会使用CAS操作实现锁,而不是相反

如果两个线程使用相同的键在空映射上调用
putIfAbsent
,两个线程都可以进行查找以查看该键是否不存在,那么两个线程是否都可以尝试添加该键

不符合以下文件:

如果指定的键尚未与值关联,请将其与给定值关联。这相当于

除此之外,操作是以原子方式执行的


这意味着两个线程都不可能尝试插入键值对。

我仍然希望能够插入的线程的putIfAbsent调用返回null。对于另一个线程,putIfAbsent将返回使其进入映射的其他线程值?@Brian correct,如果执行get(),您将看到您期望的值。您可以发布代码片段吗?魔鬼在于细节。
if (!map.containsKey(key))
    return map.put(key, value);
else
    return map.get(key);