死锁案例以及如何避免死锁

25 阅读1分钟
/**
 * 可能造成死锁
 */
public class Account {
    private int balance;
    void transfer(Account target,int amt){
        synchronized (this){
            synchronized (target){
                if(this.balance>amt){
                    this.balance-=amt;
                    target.balance+=amt;
                }
            }
        }
    }
}

当两个线程分别持有其中的一把锁时,会进入阻塞状态,且都不会释放资源: 解决方案【1】:破坏占用且等待条件

public class Allocator {
    private List<Object> als=new ArrayList();
    synchronized boolean apply(Object from,Object to){
        if(als.contains(from)||als.contains(to)){
            return false;
        }else{
            als.add(from);
            als.add(to);
            return true;
        }
    }
    synchronized void free(Object from ,Object to){
        als.remove(from);
        als.remove(to);
    }


}
public class Account2 {
    private Allocator actr;
    private int id;
    private int balance;
    //破坏占用且等待条件
    void transfer(Account2 target,int amt){
        while(!actr.apply(this,target))
            ;
        try{
            synchronized (this){
                synchronized (target){
                    if(this.balance>amt){
                        this.balance-=amt;
                        target.balance+=amt;
                    }
                }
            }

        }finally {
            actr.free(this,target);
        }
    }
    //破坏循环等待条件【2】
    void transfer2(Account2 target,int amt){
       Account2 left =this;
       Account2 right =target;
       if(this.id>target.id){
           left =target;
           right=this;
       }
        try{
            synchronized (left){
                synchronized (right){
                    if(this.balance>amt){
                        this.balance-=amt;
                        target.balance+=amt;
                    }
                }
            }

        }finally {
            actr.free(this,target);
        }
    }
}