你的位置:首页 > ASP.net教程

[ASP.net教程]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