1. “.equals()” should not be used to test the values of “Atomic” classes
级别:bug
AtomicInteger, and AtomicLong extend Number, but they’re distinct from Integer and Long and should be handled differently. AtomicInteger and AtomicLong are designed to support lock-free, thread-safe programming on single variables. As such, an AtomicInteger will only ever be “equal” to itself. Instead, you should .get() the value and make comparisons on it.
This applies to all the atomic, seeming-primitive wrapper classes: AtomicInteger, AtomicLong, and AtomicBoolean.
Noncompliant Code Example
AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);
if (aInt1.equals(aInt2)) { ... } // Noncompliant
Compliant Solution
AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);
if (aInt1.get() == aInt2.get()) { ... }
Atomic类相等与否的判断不能使用equals()方法,Atomic的作用为了在多线程情况下保持单个变量的线程安全性。Atomic变量永远只会和自身相等,如果要判断Atomic变量是否相等,应该使用get()方法获取值之后再进行判断。
AtomicInteger VS Integer
Integer类重写了Object的equals()方法,根据值的大小判断是否相等:
源码:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
而AtomicInteger没有重写equals()方法,当使用equals()时,实际上使用的是Object的equals()方法,最终判断的是对象的地址是否相等
源码:
public boolean equals(Object obj) {
return (this == obj);
}
Object的equals()描述:只有当x和y指向相同的引用时,equals()才返回true