C# Monitor class in multithreading (with examples)

CSharp Monitor class in multithreading
C# Monitor class in multithreading

What Is Monitor Class In C#?

C# Monitor: The Monitor class in C# provides a wait-based synchronization mechanism that allows only one thread to access a critical section of code at a time to avoid the race condition.
All the other threads have to wait and halt the execution until the locked object is released.

The  Monitor.Enter  method is used to acquire an exclusive lock on the object whereas  Monitor.Exit  method is used to release the locked object.

In order to use the Monitor class in a multithreading , we first need to import the  System.Threading  namespace.

Monitor Class in Multithreading in C#
Monitor Class in Multithreading in C#

C# Monitor Syntax

The following is the syntax to declare monitor class in C#

static object _lock = new object();
// Lock object
Monitor.Enter(_lock);
try
{
  // Critical piece of code
}

finally
{
 // Releasing object
   Monitor.Exit(_lock);
}

Example: C# Monitor Class in Multithreading

Following is the example of the Monitor class in C#

using System;
using System.Threading;
namespace MontitorExample
{
 class Program
  {
 static object _lock = new object();

 public static void PrintNumber()
  {   
  // Lock object

  Monitor.Enter(_lock);
  try
   {
    // Critical piece of code
              
    int threadId = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine($" Thread: {threadId} Entered into the critical section ");

    for (int num = 1; num <= 3; num ++)
     {

      Console.WriteLine($" num: {num}");
    //Pausing the thread execution for 2 seconds

      Thread.Sleep(TimeSpan.FromSeconds(2));

      }
   }

  catch (SynchronizationLockException exception)
      {
       Console.WriteLine(exception.Message);
      }

  finally
    { 
     // Releasing object
      Monitor.Exit(_lock);
      Console.WriteLine($"Thread : {Thread.CurrentThread.ManagedThreadId} Released");
    }           
  }
  static void Main(string[] args)
   {        
   // Creating threads
   Thread thread1 = new Thread(PrintNumber);
   Thread thread2 = new Thread(PrintNumber);

  // Executing the threads
   thread1.Start();
   thread2.Start();

  Console.ReadLine();      
   }
 }

}

Let’s run the above program to see the result.

C# Monitor class output
C# Monitor: The output of the above c# program

Methods of the Monitor class

The Monitor class is a static class which contains the following methods:

      • Monitor.Enter
      • Monitor.TryEnter
      • Monitor.Exit
      • Monitor.Pulse
      • Monitor.PulseAll
      • Monitor.Wait

Monitor.Enter, Monitor.TryEnter : These methods are used to acquire an exclusive lock on the object, which allows only one thread to access the critical section of code at a time.

Monitor.Pulse, Monitor.PulseAll : A thread sends the signal to one or multiple threads in the waiting queue that the state of the locked object has been changed. So, that they can proceed with the further process.

Monitor.Wait(): This method is used to release the locked object after getting the Pulse notification to allow other threads to lock and access the object.

The calling threads wait in the waiting queue while the other thread is allowed to access the object until it gets the pulse notification.

Note: Wait() method must execute before the Pulse or PulseAll method to get the pulse notification.

Monitor.Exit: This method is used to release the locked object, and it is always declared inside finally block.

Difference between Lock and Monitor in C#

In C#, Both the  Lock  and  Monitor   class are basically used to ensure that only one thread can access a particular section of code at a time. 

The following are the basic differences between both classes:

    • A lock statement is a short form of the Monitor class which internally wraps the methods  Monitor.Enter  and  Monitor.Exit  with an additional  try/finally  block, to perform the thread-safe operation, whereas in the case of Monitor class, we have to declare try and finally block explicitly to  release the locked object.
    • Apart from the synchronization mechanism, the Monitor class provides some useful methods like Wait(), Pulse(), and PulseAll() for the signaling mechanism between the threads. However, the lock doesn’t support the signaling mechanism.
    • The monitor is a static class that can’t be instantiated.

FAQs

Here are some frequently asked questions (FAQs) about the C# Monitor class and its usage in managing thread synchronization:

Q: What is the C# Monitor class?

The C# Monitor class is a mechanism for thread synchronization that allows exclusive access to shared resources. It helps prevent race conditions and ensures safe concurrent access to critical sections of code.

Q: Are there any alternatives to the Monitor class for thread synchronization?

Yes, C# provides other synchronization mechanisms, such as Mutex, Semaphore, and ManualResetEvent, which can be used based on the specific synchronization requirements of the application.

Q: What happens if a thread forgets to release the lock acquired with the Monitor class?

If a thread forgets to release the lock, it can cause deadlock, where all threads waiting for the lock remain stuck indefinitely. Proper care should be taken to ensure the lock is always released after use.

Q: Is the Monitor class limited to managing synchronization for only shared variables?

No, the Monitor class can be used for synchronization in any critical section of code that needs exclusive access by multiple threads, not just limited to shared variables.

Q: Are monitors better than semaphores?

Monitors and semaphores are different synchronization mechanisms, and neither is inherently better than the other. 

The choice between monitors and semaphores depends on the specific requirements of the multi-threaded application. Monitors are suitable for managing exclusive access to shared resources within the same process, while semaphores are useful for more complex synchronization scenarios involving multiple processes.

Each has its strengths and should be selected based on the specific needs of the application.

When should we use the monitor wait method?

The Monitor.Wait() execute before the Pulse or PulseAll methods, It is used to block a process’s execution and to release the locked object after getting the Pulse notification to allow other threads to lock and access the object.

The Monitor.Wait() method is an overloaded method that can have a timeout parameter to make sure that If the specified time-out interval elapses, the current thread enters the ready queue.

Conclusion

In C#, The Lock and Monitor classes are generally used for synchronization purposes in a multithreading environment.
They allow only one thread to access a critical section of code at a time.
The only major difference between both of them is that the Monitor class provides more control over synchronization by using the signaling mechanism.

Thank you for taking the time to read the blog, if you find it interesting, please like, comment, and share it with others.

Articles to Check Out

Shekh Ali
4.5 2 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments