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();
                    }
                }
            }
        }
    }
  • 相关阅读:
    C#-WebForm-★★★JQuery-动画★★★
    C#-WebForm-★★★JQuery知识——DOM操作★★★
    C#-WebForm-★★★JQuery知识——基础知识、选择器、事件★★★
    C#-WebForm-组合查询(Queryable延迟查询、Intersect交集)、分页展示基础
    C#-WebForm-★★★LinQ-数据的条件组合查询并进行分页展示(未加各种限定)★★★
    C#-WebForm-光棒效果
    C#-WebForm-LinQ-条件精确查询、高级查询
    C#-WebForm-LinQ(一)-LinQ:语言集成查询(Language Integrated Query)-增删改查、属性扩展
    C#-WebForm JS定时器
    ★★★正则表达式★★★
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/6189171.html
Copyright © 2011-2022 走看看