这几天一直困扰着我,所以我正在寻找一个具体的答案。
(请多多包涵,我并不是要编写漂亮的代码。相反,我正在寻找有气味的代码的问题)
想象一下,我们有一个来自类的有状态对象Foo
public class Foo {
public int attribute = 0;
// hashCode implemented :P
@Override
public boolean equals(Object o) {
if (o instanceof Foo) {
Foo that = (Foo) o;
return this.attribute == that.attribute;
}
return false;
}
}
我们在 Foo 上有一些工人
public class DoomBringer implements Runnable {
private final Foo foo;
public DoomBringer(Foo foo) {
this.foo = foo;
}
@Override
public void run() {
this.foo.attribute++;
}
}
另一个只打印#equals
作为参数传递给其构造函数的对象的结果。
public class SelfEqualityTestPrinter implements Runnable {
private final Foo foo;
public SelfEqualityTestPrinter(Foo foo) {
this.foo = foo;
}
@Override
public void run() {
System.out.println(foo.equals(foo));
}
}
如果我们有并发线程修改同一个实例,是否有可能false
有一天会打印出来?Foo
我的猜测是这是可能的。我不认为 equals 是同步的,除非我们这样做。避免这种情况的一种方法是this == o
在该Object#equals(Object o)
方法上进行测试,但是比较应该相等的不同实例可能会出现同样的问题。