find and solve || findandsolve.com
Please wait.....

C# Thread Synchronization

In the C#, thread synchronization primitives used to synchronize access to a shared resource or control thread interaction. It is a the mechanism that ensures that two or more concurrent processes or threads do not execute some particular section.

In a multithreading program, threads are allowed to access any resource for the required execution time. Threads share resources and execute asynchronously. Accessing shared resources (data) is a critical task that sometimes may halt the system.

Thread Synchronization Deals with the given conditions:

  1. Deadlock
  2. Starvation
  3. Priority Inversion
  4. Busy Waiting

The given are some classic problems of Synchronization:

  1. The Producer-Consumer Problem
  2. The Readers-Writers Problem
  3. The Dining Philosopher Problem

Synchronization is handled with the given four categories:

  1. Blocking Methods
  2. Locking Construct
  3. Signaling
  4. No Blocking Synchronization

Blocking Methods 

In this technique, one thread wait is waiting for another thread to finish for a particular period of time. Execution is paused for some reason. The given are some Blocking methods in C# programming language:

  1. Sleep
  2. Join
  3. Task.Wait

Sleep

It pauses the execution of a program for a defined time. It does not utilize the CPU during the pause time. It is useful for waiting on an external Task.

Thread.Sleep(300)  

Join

using System; 

using System.Threading;
namespace AnonymousMethods
{
 public class Program
 {
    static void Main(string[] args)
    {
        Thread objThread1 = new Thread(Method);
        objThread1.Start();
        Thread objThread2 = new Thread(Method);
        objThread2.Start();
        objThread1.Join();
        Console.WriteLine("After Thread1");
        objThread2.Join();
        Console.WriteLine("After Thread2");
        Console.ReadKey();
    }
    private static void Method(object obj)
    {
        Console.WriteLine("Thread1 Executed.");
    }
    private static void Method1(object obj)
    {
        Console.WriteLine("Thread2 Executed");
    }
}
}

Output

Thread2 Executed.

Thread1 Executed.

After Thread1

After Thread2 

Task.Wait 

using System; 

using System.Threading.Tasks;
namespace AnonymousMethods
{
 public class Program
 {
    public static void Main(string[] args)
    {
        Task task = Task.Run(() =>
        {
            Random randomNumbers = new Random();
            long logSum = 0;
            int count = 100;
            for (int i = 1; i <= count; i++)
            {
                int randomNumber = randomNumbers.Next(0, 101);
                logSum += randomNumber;
            }
            Console.WriteLine("Total:{0}", logSum);
            Console.WriteLine("Count: {0}", count);
        });
  task.Wait();
      }
   }
}

Output

Total:4927

Count: 100


Advantage of Thread Synchronization

  • Consistency Maintain
  • No Thread Interference


C# Lock

You can use C# lock keyword to execute the program synchronously and used to get a 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.


C# Example: Without Synchronization

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

using System;  

using System.Threading;
public class Printer
{
    public void PrintTable()
    {
        for (int i = 1; i <= 5; i++)
        {
            Thread.Sleep(100);
            Console.WriteLine("Display:{0}",i);
        }
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        Printer printer = new Printer();
        Thread objThread = new Thread(new ThreadStart(printer.PrintTable));
        Thread objThread1 = new Thread(new ThreadStart(printer.PrintTable));
        objThread.Start();
        objThread1.Start();
    }
}  

Output

Display: 1

Display: 1

Display: 2

Display: 2

Display: 3

Display: 3

Display: 4

Display: 4

Display: 5

Display: 5


C# Thread Synchronization Example

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

using System;  

using System.Threading;
class Printer
{
    public void PrintTable()
    {
        lock (this)
        {
            for (int i = 1; i <= 10; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(i);
            }
        }
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        Printer print = new Printer();
        Thread objThread = new Thread(new ThreadStart(print.PrintTable));
        Thread objThread1 = new Thread(new ThreadStart(print.PrintTable));
        objThread.Start();
        objThread1.Start();
    }
}  

Output

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

6

7

8

9

10