zoukankan      html  css  js  c++  java
  • JAVA并发编程学习笔记------锁顺序死锁

    一、需求描述:

      将资金从一个账户转移到另一个账户。

    二、程序实现:

    (1)账户类:

    public class Account {
        private long account;
    
        public Account(String user, long account) {
            this.account = account;
        }
    
        public Account() {
            super();
        }
    
        public long getAccount() {
            return account;
        }
    
        public void setAccount(long account) {
            this.account = account;
        }
    
        public void debit(long money){
            this.account -= money;
        }
    
        public void credit(long money){
            this.account += money;
        }
    }
    

      (2)资产转移类:

    public class TransMoney {
        private static final Object tieLock = new Object();
        public static void transferMoney(Account fromAccount,Account toAccount,long amount){
            synchronized (fromAccount){
                synchronized (toAccount){
                    fromAccount.debit(amount);
                    toAccount.credit(amount);
                }
            }
        }
    }
    

      (3)测试类:

    public class DemonstrateDeadLock {
        private static final int NUM_THREADS = 20;
        private static final int NUM_ACCOUNTS = 5;
        private static final int NUM_ITERATIONS = 1000000;
    
        public static void main(String[] args) {
            final Random rdn = new Random();
            final Account[] accounts = new Account[NUM_ACCOUNTS];
    
            for(int i=0;i<accounts.length;i++){
                accounts[i] = new Account();
            }
    
            class TransferThread extends Thread{
                public void run(){
                    for(int i=0;i<NUM_ITERATIONS;i++){
                        int fromAccount = rdn.nextInt(NUM_ACCOUNTS);
                        int toAccount = rdn.nextInt(NUM_ACCOUNTS);
    
                        TransMoney.transferMoney(accounts[fromAccount],accounts[toAccount],rdn.nextInt(1000));
                    }
                }
            }
    
            for(int i=0;i<NUM_THREADS;i++){
                new TransferThread().start();
            }
        }
    }
    

      (4)解析:

    上述程序容易形成死锁,原因在于多账户调用TransMoney.transferMoney时,存在锁顺序冲突,

    解决方案是使用System.identityHashCode来定义锁的顺序,消除死锁的可能性,代码实现如下:

    public static void transferMoney(final Account fromAccount,final Account toAccount,final long amount){
        class Helper{
            public void transfer(){
                fromAccount.debit(amount);
                toAccount.credit(amount);
            }
        }
    
        int fromHash = System.identityHashCode(fromAccount);
        int toHash = System.identityHashCode(toAccount);
        if(fromHash < toHash){
            synchronized (fromAccount){
                synchronized (toAccount){
                    new Helper().transfer();
                }
            }
        }else if(fromHash > toHash){
            synchronized (toAccount){
                synchronized (fromAccount){
                    new Helper().transfer();
                }
            }
        }else{
            synchronized (tieLock){
                synchronized (fromAccount){
                    synchronized (toAccount){
                        new Helper().transfer();
                    }
                }
            }
        }
    }
  • 相关阅读:
    Java实现 洛谷 P1060 开心的金明
    (Java实现) 洛谷 P1605 迷宫
    (Java实现) 洛谷 P1605 迷宫
    (Java实现)洛谷 P1093 奖学金
    (Java实现)洛谷 P1093 奖学金
    Java实现 洛谷 P1064 金明的预算方案
    Java实现 洛谷 P1064 金明的预算方案
    (Java实现) 洛谷 P1031 均分纸牌
    QT树莓派交叉编译环开发环境搭建(附多个exe工具下载链接)
    武则天红人对唐睿宗的桃色报复(如此缺少城府,注定了要在宫廷中过早地出局)
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/6189171.html
Copyright © 2011-2022 走看看