Advertisement
ivandrofly

Threading - Deadlock [Resolved]

Mar 24th, 2014
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.29 KB | None | 0 0
  1. using System;
  2. using System.Threading;
  3.  
  4. namespace Deadlock
  5. {
  6.     internal class Program
  7.     {
  8.         private static void Main(string[] args)
  9.         {
  10.             Console.WriteLine("Main Started");
  11.             Account accountA = new Account(101, 5000);
  12.             Account accountB = new Account(102, 3000);
  13.  
  14.             var accountManagerA = new AccountManager(accountA, accountB, 1000);
  15.             var t1 = new Thread(accountManagerA.Transfer);
  16.             t1.Name = "#1 Thread";
  17.  
  18.             var accountManagerB = new AccountManager(accountB, accountA, 2000);
  19.             var t2 = new Thread(accountManagerB.Transfer);
  20.             t2.Name = "#2 Thread";
  21.  
  22.             t1.Start();
  23.             t2.Start();
  24.  
  25.             t1.Join();
  26.             t2.Join();
  27.             Console.WriteLine("Main Completed");
  28.         }
  29.     }
  30.  
  31.     internal class Account
  32.     {
  33.         private double _balance;
  34.         private int _id;
  35.  
  36.         public int ID { get { return _id; } }
  37.  
  38.         public Account(int id, int balance)
  39.         {
  40.             this._id = id;
  41.             this._balance = balance;
  42.         }
  43.  
  44.         public void WitdhDraw(double amount)
  45.         {
  46.             _balance -= amount;
  47.         }
  48.  
  49.         public void Deposit(double amount)
  50.         {
  51.             _balance += amount;
  52.         }
  53.     }
  54.  
  55.     internal class AccountManager
  56.     {
  57.         private Account _fromAccount;
  58.         private Account _toAccount;
  59.         private int _amountToTransfer;
  60.  
  61.         public AccountManager(Account fromAccount, Account toAccount, int amountToTransfer)
  62.         {
  63.             this._fromAccount = fromAccount;
  64.             this._toAccount = toAccount;
  65.             this._amountToTransfer = amountToTransfer;
  66.         }
  67.  
  68.         /*
  69.         public void Transfer()
  70.         {
  71.             // issue
  72.             lock (_fromAccount)
  73.             {
  74.                 Thread.Sleep(1000);
  75.                 lock (_toAccount)
  76.                 {
  77.                     _fromAccount.WitdhDraw(_amountToTransfer);
  78.                     _toAccount.Deposit(_amountToTransfer);
  79.                 }
  80.             }
  81.         }
  82.         */
  83.  
  84.         public void Transfer()
  85.         {
  86.             // resolved
  87.             object lock1, lock2;
  88.  
  89.             if (_fromAccount.ID < _toAccount.ID)
  90.             {
  91.                 lock1 = _fromAccount;
  92.                 lock2 = _toAccount;
  93.             }
  94.             else
  95.             {
  96.                 lock1 = _toAccount;
  97.                 lock2 = _fromAccount;
  98.             }
  99.  
  100.             Console.WriteLine(Thread.CurrentThread.Name + " tyring to acquire lock" + ((Account)lock1).ID);
  101.             lock (lock1) // lock1
  102.             {
  103.                 Console.WriteLine(Thread.CurrentThread.Name + " tyring to acquire lock" + ((Account)lock1).ID);
  104.                 Thread.Sleep(1000);
  105.                 Console.WriteLine(Thread.CurrentThread.Name + " back in action and try to acquire lock2" + ((Account)lock2).ID);
  106.                 lock (lock2)
  107.                 {
  108.                     Console.WriteLine(Thread.CurrentThread.Name + " tyring to acquire lock" + ((Account)lock1).ID);
  109.                     _fromAccount.WitdhDraw(_amountToTransfer);
  110.                     _toAccount.Deposit(_amountToTransfer);
  111.                     Console.WriteLine(Thread.CurrentThread.Name + " transferd " + _amountToTransfer + " from " + _fromAccount);
  112.                 }
  113.             }
  114.         }
  115.  
  116.         [System.ComponentModel.Description("This is the short hand by: @ivandrofly")]
  117.         public void Transfer2()
  118.         {
  119.             object _syncObj = _fromAccount.ID < _toAccount.ID ? _fromAccount : _toAccount;
  120.             Console.WriteLine(Thread.CurrentThread.Name + " tyring to acquire lock" + ((Account)_syncObj).ID);
  121.             lock (_syncObj)
  122.             {
  123.                 Console.WriteLine(Thread.CurrentThread.Name + " tyring to acquire lock" + ((Account)_syncObj).ID);
  124.                 Thread.Sleep(1000);
  125.                 Console.WriteLine(Thread.CurrentThread.Name + " back in action and try to acquire lock2" + ((Account)_syncObj).ID);
  126.                 _fromAccount.WitdhDraw(_amountToTransfer);
  127.                 _toAccount.Deposit(_amountToTransfer);
  128.                 Console.WriteLine(Thread.CurrentThread.Name + " transferd " + _amountToTransfer + " from " + _fromAccount);
  129.             }
  130.         }
  131.     }
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement