Как я могу изменить свой код, чтобы он был защищен от тупика? - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь понять, как работают тупики.Я знаю, что тупик - это когда 2 или более потоков заблокированы навсегда, и они ждут выхода друг друга из состояния блокировки, но это никогда не происходит.У меня есть следующий код, и я хочу изменить его, чтобы защитить его от тупиковой ситуации.Может кто-нибудь сказать мне, как это сделать и объяснить мне, чтобы понять это?

public class CList extends Thread {
private int item;
private Clist next;
private int updateCount=0;
public synchronized void replace(int old, int neww, Clist startedAt) {
if(item==old) {
item=neww;
updateCount++;
}
if(next!=startedAt)
next.replace(old, neww, startedAt);
}
public void run() {
 for(int i=0; i<100; i++)
 replace(i, i-1, this);
 }

public Clist(int item, Clist next) {
this.item=item;
this.next=next;
}

public static void main(String args[]) {
 Clist clist3 = new Clist(60, null);
 Clist clist2 = new Clist(40, clist3);
 Clist clist1 = new Clist(20, clist2);
 clist3.next = clist1;
 clist1.start();
 clist2.start();
 clist3.start();
}
}

1 Ответ

0 голосов
/ 24 апреля 2019

Это зависит от предполагаемой логики.

Для согласованного обновления одного объекта нет необходимости удерживать блокировку для другого объекта, поэтому можно предотвратить тупик, не удерживая блокировку, когда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);
}

На более высоком уровне приложению может потребоваться удержание блокировки другого объекта, чтобы гарантировать, что обновления для нескольких объектов происходят определенным образом.Например, в вашем примере кода, где три потока выполняют полностью избыточную работу, реальная цель, по-видимому, заключается в создании тупика, поэтому нет способа устранить тупик и сохранить первоначальную цель.

...