1 つのフィールドのみを含む次のクラスがありますi。このフィールドへのアクセスは、オブジェクト ("this") のロックによって保護されています。equals() を実装するときは、このインスタンス (a) と他のインスタンス (b) をロックする必要があります。スレッド 1 が a.equals(b) を呼び出し、同時にスレッド 2 が b.equals(a) を呼び出すと、2 つの実装でロックの順序が逆になり、デッドロックが発生する可能性があります。
同期されたフィールドを持つクラスに equals() を実装するにはどうすればよいですか?
public class Sync {
// @GuardedBy("this")
private int i = 0;
public synchronized int getI() {return i;}
public synchronized void setI(int i) {this.i = i;}
public int hashCode() {
final int prime = 31;
int result = 1;
synchronized (this) {
result = prime * result + i;
}
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Sync other = (Sync) obj;
synchronized (this) {
synchronized (other) {
// May deadlock if "other" calls
// equals() on "this" at the same
// time
if (i != other.i)
return false;
}
}
return true;
}
}