我如何修改我的代码,以免死锁?

时间:2019-04-20 21:05:09

标签: java multithreading concurrency deadlock

我试图了解死锁的工作原理。我知道死锁是指两个或多个线程永远被阻塞,并且它们彼此等待退出阻塞状态,但是这种情况永远不会发生。 我有以下代码,我想对其进行修改以使其免受死锁的影响。有人可以告诉我该怎么做并向我解释以了解它吗?

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 :(得分:0)

这取决于预期的逻辑。

为了对单个对象进行一致的更新,无需为其他对象持有锁,因此可以通过在调用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);
}

在更高级别上,应用程序可能需要按住其他对象的锁,以确保对多个对象的更新以某种方式发生。例如。在您的示例代码中,三个线程完全完成了冗余工作,实际目的似乎是产生死锁,因此无法消除死锁并保留原始目的。