死锁条件及破坏死锁条件


一、什么是死锁?

死锁是指一组线程因为竞争资源而相互等待,导致永久阻塞的现象叫死锁

二、死锁发生的条件

  1. 互斥,共享资源 X 和 Y 只能被一个线程占用(锁的本身以互斥为前提)
  2. 占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不释放共享资源 X(可破坏:一次性申请所有需要的资源)
  3. 不可抢占,其他线程不能强行抢占线程 T1 占有的资源(可破坏:没有竞争到资源的线程主动释放占有的资源)
  4. 循环等待,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占 有的资源,就是循环等待(可破坏:改变执行的顺序)

三、破坏死锁条件

/**
 * 账户信息
 */
public class Account {
    private String accountName;
    private int balance; //余额
    public Account(String accountName, int balance) {
        this.accountName = accountName;
        this.balance = balance;
    }
    public String getAccountName() {
        return accountName;
    }
    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }
    public int getBalance() {
        return balance;
    }
    public void setBalance(int balance) {
        this.balance = balance;
    }
    public void debit(int amount){
        this.balance-=amount;
    }
    public void credbit(int amount){
        this.balance+=amount;
    }
}
/**
 * 转账操作---->死锁
 */
public class TransferAccount implements Runnable{
    private Account fromAccount;
    private Account toAccount;
    private int amount;

    public TransferAccount(Account fromAccount, Account toAccount, int amount) {
        this.fromAccount = fromAccount;
        this.toAccount = toAccount;
        this.amount = amount;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (fromAccount) {
                synchronized (toAccount) {
                    if (fromAccount.getBalance() > amount) {
                        fromAccount.debit(amount);
                        toAccount.credbit(amount);
                        System.out.println(Thread.currentThread().getName() + "=======>" + fromAccount.getAccountName() + "=======>" + fromAccount.getBalance());
                        System.out.println(Thread.currentThread().getName() + "=======>" + toAccount.getAccountName() + "=======>" + toAccount.getBalance());
                    }
                }
            }
        }
    }
}
/**
 * 分配一角色统一分配互斥资源
 */
public class Allocator {
    private List<Object> list = new ArrayList<>();

    synchronized boolean apply(Object from,Object to){
        if (list.contains(from) || list.contains(to)){
            return false;
        }
        list.add(from);
        list.add(to);
        return true;
    }

    synchronized void free(){
        list.clear();
    }
}
/**
 * 转账--->一次性获取全部资源
 */
public class TransferAccount02 implements Runnable {
    private Account fromAccount;
    private Account toAccount;
    private int amount;
    private Allocator allocator;

    public TransferAccount02(Account fromAccount, Account toAccount, int amount, Allocator allocator) {
        this.fromAccount = fromAccount;
        this.toAccount = toAccount;
        this.amount = amount;
        this.allocator = allocator;
    }

    @Override
    public void run() {
        while (true) {
            if (allocator.apply(fromAccount, toAccount)) {
                try {
                    if (fromAccount.getBalance() > amount) {
                        fromAccount.debit(amount);
                        toAccount.credbit(amount);
                        System.out.println(Thread.currentThread().getName() + "=======>" + fromAccount.getAccountName() + "=======>" + fromAccount.getBalance());
                        System.out.println(Thread.currentThread().getName() + "=======>" + toAccount.getAccountName() + "=======>" + toAccount.getBalance());
                    }
                }finally {
                    allocator.free();
                }
            }
        }

    }
}
/**
 * 尝试获取资源--->不阻塞
 */
public class TransferAccount03 implements Runnable{
    private Account fromAccount;
    private Account toAccount;
    private int amount;
    static Lock fromLock = new ReentrantLock();
    static Lock toLock = new ReentrantLock();

    public TransferAccount03(Account fromAccount, Account toAccount, int amount) {
        this.fromAccount = fromAccount;
        this.toAccount = toAccount;
        this.amount = amount;
    }

    @Override
    public void run() {
        while (true) {
            if(fromLock.tryLock()){
                if(toLock.tryLock()){
                    if (fromAccount.getBalance() > amount) {
                        fromAccount.debit(amount);
                        toAccount.credbit(amount);
                        System.out.println(Thread.currentThread().getName() + "=======>" + fromAccount.getAccountName() + "=======>" + fromAccount.getBalance());
                        System.out.println(Thread.currentThread().getName() + "=======>" + toAccount.getAccountName() + "=======>" + toAccount.getBalance());
                    }
                }
            }
        }
    }
}
/**
 * @author moxiufeng
 * @date 2021/6/10 18:03
 */
public class AccountTest {
    public static void main(String[] args) {
        Account account01 = new Account("张三",20000);
        Account account02= new Account("李四",20000);

        ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(2);
        /*TransferAccount transferAccount01 = new TransferAccount(account01,account02,20);
        TransferAccount transferAccount02 = new TransferAccount(account02,account01,10);*/

        Allocator allocator = new Allocator();
        TransferAccount02 transferAccount01 = new TransferAccount02(account01,account02,20,allocator);
        TransferAccount02 transferAccount02 = new TransferAccount02(account02,account01,10,allocator);

        /*TransferAccount03 transferAccount01 = new TransferAccount03(account01,account02,20);
        TransferAccount03 transferAccount02 = new TransferAccount03(account02,account01,10);*/

        executorService.submit(transferAccount01);
        executorService.submit(transferAccount02);
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值