繁体   English   中英

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

[英]Does java.util.concurrent.ConcurrentHashMap.putIfAbsent need to be in a syncronized block?

我试图追踪竞争条件,所有迹象似乎都指向ConcurrentHashMap.putIfAbsent() 是否有可能如果2个线程在空映射上调用putIfAbsent()并使用相同的键来执行查找以查看密钥是否存在,那么两个线程是否都会尝试添加它? 由于某些原因,当我第一次开始使用putIfAbsent()我认为调用不需要同步。 但是现在我看不出如果时机合适,它会如何阻止两个线程添加它们的值。 我无法在生产之外重现这一点。

谢谢

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

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

是否有可能如果2个线程在空映射上调用putIfAbsent()并使用相同的键来执行查找以查看密钥是否存在,那么两个线程是否都会尝试添加它?

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

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

它没有。

但是现在我看不出如果时机合适,它会如何阻止两个线程添加它们的值。

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

是否有可能如果2个线程在一个空映射上调用putIfAbsent并使用相同的键,两个都可以进行查找以查看密钥是否存在,那么两个线程都会尝试添加它?

不是根据putIfAbsent()的文档:

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

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

除了动作以原子方式执行

这意味着两个线程都无法尝试插入键值对。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM