Part 95 to 96 Deadlock in a multithreaded program

Part 95   Deadlock in a multithreaded program

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("main start");
            Account a1 = new Account(001,10000);
            Account a2 = new Account(002,20000);
            AccountManager m1 = new AccountManager(a1,a2,5000);
            Thread t1 = new Thread(m1.Transfer);
            t1.Name = "t1";
            AccountManager m2 = new AccountManager(a2, a1, 3000);
            Thread t2 = new Thread(m2.Transfer);
            t2.Name = "t2";
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
            Console.WriteLine("main end");
        }
    }

    class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
        public Account(int id, double balance)
        {
            this.ID = id;
            this.Balance = balance;
        }
        public void WithDraw(double amount)
        {
            Balance -= amount;
        }
        public void Deposit(double amount)
        {
            Balance += amount;
        }
    }

    class AccountManager
    {
        public Account FromAccount { get; set; }
        public Account ToAccount { get; set; }
        public double AmountToTransfer { get; set; }
        public AccountManager(Account from,Account to,double amountToTransfer)
        {
            this.FromAccount = from;
            this.ToAccount = to;
            this.AmountToTransfer = amountToTransfer;
        }
        public void Transfer()
        {
            Console.WriteLine(Thread.CurrentThread.Name+"try to acquire lock on"+FromAccount.ID.ToString());
            lock (FromAccount)
            {
                Console.WriteLine(Thread.CurrentThread.Name+" acquired lock on "+FromAccount.ID.ToString());
                Console.WriteLine(Thread.CurrentThread.Name+" suspended for 1 second");
                Thread.Sleep(1000);
                Console.WriteLine(Thread.CurrentThread.Name+"back in action and try to acquire lock on" +ToAccount.ID.ToString());
                lock (ToAccount)
                {
                    Console.WriteLine("this code will not execute");
                    FromAccount.WithDraw(AmountToTransfer);
                    ToAccount.Deposit(AmountToTransfer);
                }
            }
        }

    }
View Code

Part 96   How to resolve a deadlock in a multithreaded program

static void Main(string[] args)
        {
            Console.WriteLine("main start");
            Account a1 = new Account(101,10000);
            Account a2 = new Account(102,20000);
            AccountManager m1 = new AccountManager(a1,a2,5000);
            Thread t1 = new Thread(m1.Transfer);
            t1.Name = "t1";
            AccountManager m2 = new AccountManager(a2, a1, 3000);
            Thread t2 = new Thread(m2.Transfer);
            t2.Name = "t2";
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
            Console.WriteLine("main end");
        }
    }

    class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
        public Account(int id, double balance)
        {
            this.ID = id;
            this.Balance = balance;
        }
        public void WithDraw(double amount)
        {
            Balance -= amount;
        }
        public void Deposit(double amount)
        {
            Balance += amount;
        }
    }

    class AccountManager
    {
        public Account FromAccount { get; set; }
        public Account ToAccount { get; set; }
        public double AmountToTransfer { get; set; }
        public AccountManager(Account from,Account to,double amountToTransfer)
        {
            this.FromAccount = from;
            this.ToAccount = to;
            this.AmountToTransfer = amountToTransfer;
        }
        public void Transfer()
        {
            object _lock1, _lock2;
            if(FromAccount.ID<ToAccount.ID)
            {
                _lock1 = FromAccount;
                _lock2 = ToAccount;
            }
            else
            {
                _lock1 = ToAccount;
                _lock2 = FromAccount;
            }
            Console.WriteLine(Thread.CurrentThread.Name+"try to acquire lock on "+((Account)_lock1).ID.ToString());
            lock (_lock1)
            {
                Console.WriteLine(Thread.CurrentThread.Name + " acquired lock on " + ((Account)_lock1).ID.ToString());
                Console.WriteLine(Thread.CurrentThread.Name+" suspended for 1 second");
                Thread.Sleep(1000);
                Console.WriteLine(Thread.CurrentThread.Name + "back in action and try to acquire lock on " + ((Account)_lock2).ID.ToString());
                lock (_lock2)
                {
                    Console.WriteLine(Thread.CurrentThread.Name + " acquired lock on " + ((Account)_lock2).ID.ToString());
                    FromAccount.WithDraw(AmountToTransfer);
                    ToAccount.Deposit(AmountToTransfer);
                    Console.WriteLine(Thread.CurrentThread.Name+" Transferd "+AmountToTransfer.ToString()+" from "+FromAccount.ID.ToString()+" to "+ToAccount.ID.ToString());
                }
            }
        }
View Code

原文地址:https://www.cnblogs.com/gester/p/4870467.html