Это зависит от предполагаемой логики.
Для согласованного обновления одного объекта нет необходимости удерживать блокировку для другого объекта, поэтому можно предотвратить тупик, не удерживая блокировку, когдаinvoking next.replace(…)
:
public void replace(int old, int neww, Clist startedAt) {
synchronized(this) {
if(item==old) {
item=neww;
updateCount++;
}
}
if(next!=startedAt)
next.replace(old, neww, startedAt);
}
На более высоком уровне приложению может потребоваться удержание блокировки другого объекта, чтобы гарантировать, что обновления для нескольких объектов происходят определенным образом.Например, в вашем примере кода, где три потока выполняют полностью избыточную работу, реальная цель, по-видимому, заключается в создании тупика, поэтому нет способа устранить тупик и сохранить первоначальную цель.