Avoid Deadlock example

前端 未结 6 2090
谎友^
谎友^ 2020-12-13 04:51

I am wondering what are the alternative ways to avoid deadlock in the following example. The following example is a typical bank account transferring deadlock problem. What

6条回答
  •  时光取名叫无心
    2020-12-13 05:28

    Here is the solution for the problem stated.

    import java.util.Random;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class FixDeadLock1 {
    
        private class Account {
    
            private final Lock lock = new ReentrantLock();
    
            @SuppressWarnings("unused")
            double balance;
            @SuppressWarnings("unused")
            int id;
    
            public Account(int id, double balance) {
                this.balance = balance;
                this.id = id;
            }
    
            void withdraw(double amount) {
                this.balance -= amount;
            }
    
            void deposit(double amount) {
                balance += amount;
            }
        }
    
        private class Transfer {
    
            void transfer(Account fromAccount, Account toAccount, double amount) {
                /*
                 * synchronized (fromAccount) { synchronized (toAccount) {
                 * fromAccount.withdraw(amount); toAccount.deposit(amount); } }
                 */
    
                if (impendingTransaction(fromAccount, toAccount)) {
                    try {
                        System.out.format("Transaction Begins from:%d to:%d\n",
                                fromAccount.id, toAccount.id);
                        fromAccount.withdraw(amount);
                        toAccount.deposit(amount);
                    } finally {
                        fromAccount.lock.unlock();
                        toAccount.lock.unlock();
                    }
    
                } else {
                     System.out.println("Unable to begin transaction");
                }
    
            }
    
            boolean impendingTransaction(Account fromAccount, Account toAccount) {
    
                Boolean fromAccountLock = false;
                Boolean toAccountLock = false;
    
                try {
                    fromAccountLock = fromAccount.lock.tryLock();
                    toAccountLock = toAccount.lock.tryLock();
                } finally {
                    if (!(fromAccountLock && toAccountLock)) {
                        if (fromAccountLock) {
                            fromAccount.lock.unlock();
                        }
                        if (toAccountLock) {
                            toAccount.lock.unlock();
                        }
                    }
                }
    
                return fromAccountLock && toAccountLock;
            }
    
        }
    
        private class WrapperTransfer implements Runnable {
            private Account fromAccount;
            private Account toAccount;
            private double amount;
    
            public WrapperTransfer(Account fromAccount,Account toAccount,double amount){
                this.fromAccount = fromAccount;
                this.toAccount = toAccount; 
                this.amount = amount;
            }
    
            public void run(){
                Random random = new Random();
                try {
                    int n = random.nextInt(1000);
                    int TIME = 1000 + n; // 1 second + random delay to prevent livelock
                    Thread.sleep(TIME);
                } catch (InterruptedException e) {}
                new Transfer().transfer(fromAccount, toAccount, amount);
            }
    
        }
    
        public void initiateDeadLockTransfer() {
            Account from = new Account(1, 1000);
            Account to = new Account(2, 300);       
            new Thread(new WrapperTransfer(from,to,200)).start();
            new Thread(new WrapperTransfer(to,from,300)).start();
        }
    
        public static void main(String[] args) {
            new FixDeadLock1().initiateDeadLockTransfer();
        }
    
    }
    

提交回复
热议问题