У меня есть следующий класс, который содержит только одно поле i
. Доступ к этому полю защищен блокировкой объекта ("this"). При реализации equals() мне нужно заблокировать этот экземпляр (a) и другой (b). Если поток 1 вызывает a.equals(b), и в то же время поток 2 вызывает b.equals(a), порядок блокировки является обратным в двух реализациях и может привести к тупиковой ситуации.
Как мне реализовать 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;
}
}