为什么两个原子集成商永远不会相等?

2022-09-01 09:42:40

我偶然发现了来源,并意识到AtomicInteger

new AtomicInteger(0).equals(new AtomicInteger(0))

计算结果为 。false

这是为什么呢?是与并发问题相关的一些“防御性”设计选择吗?如果是这样,如果以不同的方式实施,会有什么问题?

(我确实意识到我可以使用和代替。get==


答案 1

这部分是因为 a 不是 的通用替换。AtomicIntegerInteger

包摘要指出:java.util.concurrent.atomic

原子类不是相关类的通用替换。它们不定义诸如 和 之类的方法。(由于原子变量预计会发生突变,因此它们是哈希表键的不良选择。java.lang.IntegerhashCodecompareTo

hashCode未实现,的情况也是如此。这部分是由于邮件列表存档中讨论的一个更大的理由,即是否应该扩展。equalsAtomicIntegerNumber

AtomicXXX 类不是原语的直接替代品,并且它没有实现接口的原因之一是,在大多数情况下比较 AtomicXXX 类的两个实例是毫无意义的。如果两个线程可以访问和改变 的值,则在使用结果之前,如果一个线程改变了 AtomicInteger 的值,则比较结果无效。同样的理由也适用于该方法 - 相等性检验的结果(取决于 的值)仅在线程突变其中一个有问题的s之前有效。ComparableAtomicIntegerequalsAtomicIntegerAtomicInteger


答案 2

从表面上看,这似乎是一个简单的遗漏,但实际上只使用由Object.equals

例如:

AtomicInteger a = new AtomicInteger(0)
AtomicInteger b = new AtomicInteger(0)

assert a.equals(b)

似乎是合理的,但不是真的,它被设计为一个值的可变持有者,因此不能在程序中真正取代。baa

也:

assert a.equals(b)
assert a.hashCode() == b.hashCode()

应该工作,但如果b的值在两者之间变化怎么办。

如果这是一个遗憾的原因,它没有记录在源代码中。AtomicInteger

顺便说一句:一个不错的功能也可能是允许等于整数。AtomicInteger

AtomicInteger a = new AtomicInteger(25);

if( a.equals(25) ){
    // woot
}

麻烦的意思是,为了在这种情况下具有自反性,Integer也必须接受它的相等性。AtomicInteger


推荐