繁体   English   中英

OpenJDK和Oracle JDK之间computeIfAbsent的语义差异

[英]Difference in semantics of computeIfAbsent between OpenJDK and Oracle JDK

我注意到 Oracle 的 JDK 和 Open JDK 之间的ConcurrentHashMap.computeIfAbsent方法的语义存在严重差异。 这很令人惊讶,所以我想记下它,看看其他人是否注意到了这个问题,或者我是否误解了某些东西。

根据 Oracle JDK 的 Javadoc(从 v8 开始,一直到 v15),调用 mappingFunction 的语义是:

整个方法调用以原子方式执行,因此每个键最多应用一次 function。

但是,当从两个不同的线程同时访问密钥时,我注意到 function 在我的程序中被调用了两次。 深入挖掘,我注意到 Open JDK 的文档指定了不同的语义:

整个方法调用以原子方式执行。 如果密钥不存在,则每次调用此方法时,提供的 function 仅调用一次,否则根本不调用。

这在行为上有很大的不同,并且与我在程序中观察到的一致。 在我看来,Open JDK 的实现用处不大,因为正在构建的资源通常非常昂贵,并且最多只能创建一次。

这是行为上的很大差异

没有行为差异。 它们的行为完全相同。

javadoc 的措辞已经简单地改变了。

整个方法调用是原子执行的,因此每个 key最多应用一次function 。

与:

整个方法调用以原子方式执行。 如果密钥不存在,则每次调用此方法时,提供的 function 仅调用一次,否则根本不调用。

如果两个线程对同一个键处于竞争状态,则每个线程都会调用computeIfAbsent ,因此可能会发生两次方法调用,每个线程调用一次,即每次调用 computeIfAbsent 都会调用computeIfAbsent ,如第二个版本中所述。

原子保证意味着只有一个线程将值应用于map,即 function 的结果仅应用于相关密钥一次,如第一个版本中所述。 其他线程进行的 function 调用的结果被简单地丢弃。

如您所见,两个版本的 javadoc 描述都准确地描述了方法的行为。 这些描述并不相互矛盾,因为它们描述了行为的两个不同方面

暂无
暂无

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

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