Complete C# Tutorial

Thread Lock & Monitor in C# - Explained with Easy Examples!

Hey there, fellow C# coder! πŸ‘‹ Have you ever faced random data corruption in multithreading? 🀯 Or maybe two threads modifying a variable at the same time, causing unexpected results?

Well, that’s because of race conditions! 😱 But don’t worry! We can fix this using Thread Lock in C# and Thread Monitor in C#.

Today, I’ll break down both lock and Monitor, show you the differences, and explain when to use them. By the end, you’ll write thread-safe code like a pro! πŸš€

πŸš€ Why Do We Need Thread Locking?

Imagine two people trying to withdraw money from the same bank account at the same time.

  • Person A checks the balance ($500) and tries to withdraw $400.
  • At the exact same time, Person B checks the balance ($500) and tries to withdraw $300.
  • Both transactions go through… but wait, we only had $500! 😱

Oops! Data inconsistency happened because two threads accessed the same resource (bank balance) simultaneously.

To prevent this, we use Thread Lock in C# and Thread Monitor in C# to ensure only one thread can access shared data at a time.

πŸ”’ What is lock in C#?

The lock keyword ensures only one thread can enter a critical section at a time.
It’s the simplest and most commonly used way to handle thread safety.

Β 

βœ… Syntax of lock

				
					lock (lockObject)
{
    // Critical section (Only one thread can access this block at a time)
}
				
			

πŸ† Example 1: Using lock to Prevent Race Conditions

Let’s see how lock helps in a multithreading scenario.

				
					using System;
using System.Threading;

class Program
{
    static int counter = 0;
    static object lockObj = new object(); // Lock object

    static void Increment()
    {
        for (int i = 0; i < 1000; i++)
        {
            lock (lockObj) // Only one thread can enter this block
            {
                counter++;
            }
        }
    }

    static void Main()
    {
        Thread t1 = new Thread(Increment);
        Thread t2 = new Thread(Increment);

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

        Console.WriteLine($"Final Counter Value: {counter}"); // Always 2000
    }
}
				
			

βœ… Output (Correct Now!)

				
					Final Counter Value: 2000
				
			

πŸŽ‰ Problem solved! Without lock, the counter value would be incorrect due to race conditions.

πŸ•΅οΈ What is Monitor in C#?

The Monitor class provides more fine-grained control over thread synchronization than lock.
It allows:

βœ”οΈ Entering the critical section (Monitor.Enter()).
βœ”οΈ Exiting the critical section (Monitor.Exit()).
βœ”οΈ Waiting for another thread (Monitor.Wait()).

Β 

βœ… Syntax of Monitor

				
					Monitor.Enter(lockObject);
try
{
    // Critical section
}
finally
{
    Monitor.Exit(lockObject);
}
				
			

πŸ”₯ Example 2: Using Monitor for Thread Synchronization

Let’s rewrite the previous example using Monitor instead of lock.

				
					using System;
using System.Threading;

class Program
{
    static int counter = 0;
    static object lockObj = new object();

    static void Increment()
    {
        for (int i = 0; i < 1000; i++)
        {
            Monitor.Enter(lockObj); // Locking the resource
            try
            {
                counter++;
            }
            finally
            {
                Monitor.Exit(lockObj); // Always release the lock
            }
        }
    }

    static void Main()
    {
        Thread t1 = new Thread(Increment);
        Thread t2 = new Thread(Increment);

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

        Console.WriteLine($"Final Counter Value: {counter}");
    }
}
				
			

βœ… Output (Correct!)

				
					Final Counter Value: 2000
				
			

🎯 Monitor works just like lock, but gives more flexibility!

πŸ€” When to Use lock vs. Monitor?

FeaturelockMonitor
Simplicityβœ… Easy to use❌ More complex
Performanceβœ… Slightly faster❌ Slightly slower
Exception Safetyβœ… Handles automatically❌ Must use try-finally
Fine Control❌ Noβœ… Yes (can wait, signal, etc.)

πŸš€ Use lock when you need simple thread safety.
βš™οΈ Use Monitor when you need more control (waiting, signaling, etc.).

🌍 Real-World Example: Ticket Booking System

Imagine an online ticket booking system 🎟️.

  • If two users try to book the last ticket at the same time, both might get a successful booking confirmation.
  • This is wrong!
  • To prevent this, we use lock or Monitor to ensure only one user can book at a time.
				
					using System;
using System.Threading;

class TicketBooking
{
    static int availableSeats = 1;
    static object lockObj = new object();

    static void BookTicket(string name)
    {
        lock (lockObj)
        {
            if (availableSeats > 0)
            {
                Console.WriteLine($"{name} booked a ticket!");
                availableSeats--;
            }
            else
            {
                Console.WriteLine($"{name} failed to book. No seats available.");
            }
        }
    }

    static void Main()
    {
        Thread user1 = new Thread(() => BookTicket("Alice"));
        Thread user2 = new Thread(() => BookTicket("Bob"));

        user1.Start();
        user2.Start();

        user1.Join();
        user2.Join();
    }
}
				
			

βœ… Output (Only one person books a ticket!)

				
					Alice booked a ticket!
Bob failed to book. No seats available.
				
			

πŸ”₯ Boom! Problem solved! Now, only one user books the ticket.

🎯 Conclusion – Why This is Important?

βœ… Thread Lock in C# and Thread Monitor in C# prevent race conditions.
βœ… They ensure only one thread modifies shared data at a time.
βœ… Use lock for simple thread safety.
βœ… Use Monitor when you need more control over threads.

Β 

πŸš€ Next What?

πŸŽ‰ Great job! You now understand Thread Lock in C# and Thread Monitor in C#!

But wait, there’s more! πŸš€

Next up: Mutex, Semaphore & SemaphoreSlim in C# – Master Thread Synchronization! πŸ” Stay tuned! πŸš€

Leave a Comment

Share this Doc

Lock & Monitor

Or copy link