0% found this document useful (0 votes)
14 views

C Lock

This document discusses using locks in C# for thread synchronization. It provides an example of printing numbers from 1 to 10 using two threads, with the PrintTable method locked using the lock keyword. This ensures synchronous execution with the second thread starting only after the first thread completes. Without the lock, the threads would interleave asynchronously. The document also provides another example of synchronizing access to an Account balance field across threads using locking.

Uploaded by

Nenad Femic
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

C Lock

This document discusses using locks in C# for thread synchronization. It provides an example of printing numbers from 1 to 10 using two threads, with the PrintTable method locked using the lock keyword. This ensures synchronous execution with the second thread starting only after the first thread completes. Without the lock, the threads would interleave asynchronously. The document also provides another example of synchronizing access to an Account balance field across threads using locking.

Uploaded by

Nenad Femic
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 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