Suggested Videos
Part 92 - Significance of Thread.Join and Thread.IsAlive functions
Part 93 - Protecting shared resources from concurrent access in multithreading
Part 94 - Difference between Monitor and lock in C#
In this video we will discuss, why and how a deadlock can occur in multithreading with an example.
Scenario when a deadlock can occur
Let's say we have 2 threads
a) Thread 1
b) Thread 2
and 2 resources
a) Resource 1
b) Resource 2
Thread 1 has already acquired a lock on Resource 1 and wants to acquire a lock on Resource 2. At the same time Thread 2 has already acquired a lock on Resource 2 and wants to acquire a lock on Resource 1. Two threads never give up their locks, hence a deadlock.
Example code used in the demo
Part 92 - Significance of Thread.Join and Thread.IsAlive functions
Part 93 - Protecting shared resources from concurrent access in multithreading
Part 94 - Difference between Monitor and lock in C#
In this video we will discuss, why and how a deadlock can occur in multithreading with an example.
Scenario when a deadlock can occur
Let's say we have 2 threads
a) Thread 1
b) Thread 2
and 2 resources
a) Resource 1
b) Resource 2
Thread 1 has already acquired a lock on Resource 1 and wants to acquire a lock on Resource 2. At the same time Thread 2 has already acquired a lock on Resource 2 and wants to acquire a lock on Resource 1. Two threads never give up their locks, hence a deadlock.
Example code used in the demo
using System;
using System.Threading;
public class Program
{
public static void Main()
{
Console.WriteLine("Main
Started");
Account accountA = new
Account(101, 5000);
Account accountB = new
Account(102, 3000);
AccountManager accountManagerA = new
AccountManager(accountA, accountB, 1000);
Thread T1 = new
Thread(accountManagerA.Transfer);
T1.Name = "T1";
AccountManager accountManagerB = new
AccountManager(accountB, accountA, 2000);
Thread T2 = new
Thread(accountManagerB.Transfer);
T2.Name =
"T2";
T1.Start();
T2.Start();
T1.Join();
T2.Join();
Console.WriteLine("Main
Completed");
}
}
public class Account
{
double _balance;
int _id;
public Account(int id, double balance)
{
this._id = id;
this._balance = balance;
}
public int ID
{
get
{
return _id;
}
}
public void Withdraw(double amount)
{
_balance -= amount;
}
public void Deposit(double amount)
{
_balance += amount;
}
}
public class AccountManager
{
Account _fromAccount;
Account _toAccount;
double _amountToTransfer;
public AccountManager(Account fromAccount,
Account toAccount, double
amountToTransfer)
{
this._fromAccount = fromAccount;
this._toAccount = toAccount;
this._amountToTransfer = amountToTransfer;
}
public void Transfer()
{
Console.WriteLine(Thread.CurrentThread.Name
+ " trying
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 trying to acquire lock on "
+ _toAccount.ID.ToString());
lock (_toAccount)
{
_fromAccount.Withdraw(_amountToTransfer);
_toAccount.Deposit(_amountToTransfer);
}
}
}
}
hi kudvenkat sir.. why we cant have only one lock in transfer.
ReplyDeletepublic void Transfer()
{
object _lock = new object();// added only one lock
Console.WriteLine(Thread.CurrentThread.Name + " trying to acquire lock on " + _fromAccount.ID.ToString());
lock (_lock)
{
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 trying to acquire lock on " + _toAccount.ID.ToString());
//lock (_toAccount)
//{
_fromAccount.Withdraw(_amountToTransfer);
_toAccount.Deposit(_amountToTransfer);
//}
}
Console.WriteLine(Thread.CurrentThread.Name + "Completed The Transfer");
}
Lock is applicable to only one resource at a time
ReplyDelete