C Lock

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 4

C# Thread Synchronization Example

In this example, we are using lock. This example executes synchronously. In other words, there is no context-
switching between the threads. In the output section, we can see that second thread starts working after first
threads finishes its tasks.

1. using System;  
2. using System.Threading;  
3. class Printer  
4. {  
5.     public void PrintTable()  
6.     {  
7.         lock (this)  
8.         {  
9.             for (int i = 1; i <= 10; i++)  
10.             {  
11.                 Thread.Sleep(100);  
12.                 Console.WriteLine(i);  
13.             }  
14.         }  
15.     }  
16. }  
17. class Program  
18. {  
19.     public static void Main(string[] args)  
20.     {  
21.         Printer p = new Printer();  
22.         Thread t1 = new Thread(new ThreadStart(p.PrintTable));  
23.         Thread t2 = new Thread(new ThreadStart(p.PrintTable));  
24.         t1.Start();  
25.         t2.Start();  
26.     }  
27. }  

Output:

1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10
C# Lock
We can use C# lock keyword to execute program synchronously. It is used to get lock for the current
thread, execute the task and then release the lock. It ensures that other thread does not interrupt the
execution until the execution finish.

Here, we are creating two examples that executes asynchronously and synchronously.

C# Example: Without Synchronization


In this example, we are not using lock. This example executes asynchronously. In other words, there is
context-switching between the threads.

1. using System;  
2. using System.Threading;  
3. class Printer  
4. {  
5.     public void PrintTable()  
6.     {  
7.         for (int i = 1; i <= 10; i++)  
8.         {  
9.             Thread.Sleep(100);  
10.             Console.WriteLine(i);  
11.         }  
12.     }  
13. }  
14. class Program  
15. {  
16.     public static void Main(string[] args)  
17.     {  
18.         Printer p = new Printer();  
19.         Thread t1 = new Thread(new ThreadStart(p.PrintTable));  
20.         Thread t2 = new Thread(new ThreadStart(p.PrintTable));  
21.         t1.Start();  
22.         t2.Start();  
23.     }  
24. }  

Output:

1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
Example

The following example defines an Account class that synchronizes access to its private balance field by locking on
a dedicated balanceLock instance. Using the same instance for locking ensures that the balance field cannot be
updated simultaneously by two threads attempting to call the Debit or Credit methods simultaneously.

C#
using System;
using System.Threading.Tasks;

public class Account


{
private readonly object balanceLock = new object();
private decimal balance;

public Account(decimal initialBalance)


{
balance = initialBalance;
}

public decimal Debit(decimal amount)


{
lock (balanceLock)
{
if (balance >= amount)
{
Console.WriteLine($"Balance before debit :{balance, 5}");
Console.WriteLine($"Amount to remove :{amount, 5}");
balance = balance - amount;
Console.WriteLine($"Balance after debit :{balance, 5}");
return amount;
}
else
{
return 0;
}
}
}

public void Credit(decimal amount)


{
lock (balanceLock)
{
Console.WriteLine($"Balance before credit:{balance, 5}");
Console.WriteLine($"Amount to add :{amount, 5}");
balance = balance + amount;
Console.WriteLine($"Balance after credit :{balance, 5}");
}
}
}
class AccountTest
{
static void Main()
{
var account = new Account(1000);
var tasks = new Task[100];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() => RandomlyUpdate(account));
}
Task.WaitAll(tasks);
}

static void RandomlyUpdate(Account account)


{
var rnd = new Random();
for (int i = 0; i < 10; i++)
{
var amount = rnd.Next(1, 100);
bool doCredit = rnd.NextDouble() < 0.5;
if (doCredit)
{
account.Credit(amount);
}
else
{
account.Debit(amount);
}
}
}
}

You might also like