为什么两个AtomicIntegers永远不相等?

aio*_*obe 30 java concurrency equals

我偶然发现了这个来源AtomicInteger并意识到了这一点

new AtomicInteger(0).equals(new AtomicInteger(0))
Run Code Online (Sandbox Code Playgroud)

等于false.

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

(我确实知道我可以使用get而且==.)

Vin*_*lds 27

这部分是因为a AtomicInteger不是通用的替代品Integer.

该java.util.concurrent.atomic 包的摘要状态:

原子类不是通用替换 java.lang.Integer和相关类.他们没有定义像hashCode和等方法compareTo.(因为预期原子变量会发生变异,所以它们对哈希表键的选择很差.)

hashCode没有实现,情况也是如此equals.这部分是由于邮件列表档案中讨论的更大的理由,是否AtomicInteger应该延长Number.

AtomicXXX类不是基元的替代品,并且它没有实现Comparable接口的原因之一是因为在大多数情况下比较AtomicXXX类的两个实例是没有意义的.如果两个线程可以访问并改变a的值AtomicInteger,那么在使用结果之前比较结果是无效的,如果线程改变了a的值AtomicInteger.同样的理由对于该equals方法也有好处- 相等测试的结果(取决于它的值AtomicInteger)仅在线程改变其中一个AtomicIntegers 之前有效.


Gar*_*vis 10

从表面上看,这似乎是一个简单的遗漏,但也许它确实有意义实际上只是使用由提供的同一性等于 Object.equals

例如:

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

assert a.equals(b)
Run Code Online (Sandbox Code Playgroud)

似乎是合理的,但事实b并非如此a,它被设计为价值的可变持有者,因此无法a在程序中真正取代.

也:

assert a.equals(b)
assert a.hashCode() == b.hashCode()
Run Code Online (Sandbox Code Playgroud)

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

如果这是一个耻辱的原因,它没有记录在源代码中AtomicInteger.

另外:一个很好的功能也可能是允许AtomicInteger等于整数.

AtomicInteger a = new AtomicInteger(25);

if( a.equals(25) ){
    // woot
}
Run Code Online (Sandbox Code Playgroud)

麻烦它意味着,为了在这种情况下反思,整数也必须接受AtomicInteger它的平等.

  • 我看到了你的观点(这是一个很好的观点:-)其他可变类如`ArrayList`确实实现了`equals`. (2认同)
  • 我不太理解最后的评论.查看AbstractList的equals()实现.它迭代两个列表,使用equals方法逐个元素进行比较.然而,ArrayList和AtomicInteger一样可变.我认为这是一种权衡.使用AtomicInteger.equals()的便利性并不会超过它可能产生的问题.但是对于Lists来说,情况恰恰相反. (2认同)