避免死锁:通过破坏四个必要条件之一
- 破坏互斥:无法破坏,因为我们使用的是synchronized互斥锁
- 破坏占有且等待:一次性申请所有资源
实现案例:通过在内部创建一个单例的Allocator对象去申请资源,只有申请成功,才进行下一步
public class Account {
private Allocator allocator = Allocator.getInstance();
private int balance;
Account(int m){
balance = m;
}
public void transferByAllocator(Account target, int money) throws InterruptedException {
allocator.apply(this, target);
synchronized(this){
synchronized(target){
if(this.balance >= money){
target.balance += money;
this.balance -= money;
allocator.release(this, target);
}
}
}
}
}
public class Allocator {
List<Object> als = new ArrayList<>();
private static volatile dy.practice.Allocator allocator;
private Allocator(){
}
public static Allocator getInstance(){
if(allocator == null){
synchronized (Allocator.class){
allocator = new Allocator();
}
}
return allocator;
}
public synchronized void apply(Object source, Object target){
while(als.contains(source) || als.contains(target)){
try{
wait();
}catch(Exception e){
}
}
als.add(source);
als.add(target);
}
public synchronized void release(Object source, Object target){
als.remove(source);
als.remove(target);
this.notifyAll();
}
}
- 破坏不可抢占:占有资源的线程进一步申请资源时,如果申请不到,可以主动释放已经持有的资源。synchronized锁无法主动释放(申请不到,直接阻塞),Lock锁才能主动释放。
- 破坏循环等待:将资源进行线性排序,线程按照顺序申请。
案例
public class Account {
private int id;
private int balance;
void transfer(Account target, int amt){
Account first = this;
Account second = target
if (this.id > target.id) {
first = target;
second = this;
}
synchronized(first){
synchronized(second){
if (this.balance > amt){
this.balance -= amt;
target.balance += amt;
}
}
}
}
}