Thread Lock in C#
By FoxLearn 1/9/2025 4:28:59 AM 47
When working with multiple threads, there may be instances where more than one thread attempts to access a shared resource or execute a critical section of code simultaneously.
In C#, we can achieve thread safety by using locks, specifically the lock
statement and Monitor
. These mechanisms ensure that if one thread is executing a critical section of code, other threads must wait until the first thread completes its execution.
C# Locking
The lock
statement in C# is used to provide thread safety and prevent thread collisions. It works by taking a reference to an object that can be acquired by a thread. While one thread holds the lock and executes the critical code, other threads are blocked until the lock is released.
lock (obj) { // Critical section of code }
For example:
namespace ThreadLockExample { public class Program { static void Main(string[] args) { Thread t1 = new Thread(ShowMessage); Thread t2 = new Thread(ShowMessage); Thread t3 = new Thread(ShowMessage); Thread t4 = new Thread(ShowMessage); t1.Start(1); t2.Start(2); t3.Start(3); t4.Start(4); Console.Read(); } private static readonly object lockObj = new object(); static void ShowMessage(object m) { lock (lockObj) // Lock acquired on lockObj { string message = "Welcome! Executing Thread " + Convert.ToString(m) + " !\n"; Thread.Sleep(100); // Simulate work string[] words = message.Split(' '); StringBuilder sb = new StringBuilder(); foreach (var word in words) { sb.Append(word + " "); } Console.WriteLine(sb.ToString()); } } } }
The above code ensures that the threads execute one after another in a controlled sequence, thanks to the lock (lockObj)
statement. If you comment out the lock
statement, the threads will execute concurrently, potentially leading to race conditions and incorrect outputs.
Nested Locking
In some cases, you may need to lock multiple objects in a nested manner. Nested locking works by acquiring locks on inner objects first, but the lock is only fully released when the outermost lock is released.
For example:
lock (obj1) { lock (obj2) { lock (obj3) { // Critical section of code } } }
Monitor in C#
The Monitor
class provides another way to handle thread synchronization. Only one thread can acquire a particular monitor at any given time. The other threads must wait until the first thread releases the monitor.
To use Monitor
, we call Monitor.Enter()
to acquire the lock and Monitor.Exit()
to release it. This is often done within a finally
block to ensure that the lock is always released.
bool isLocked = false; object lockObj = new object(); try { Monitor.Enter(lockObj, ref isLocked); // Critical section of code } finally { if (isLocked) { Monitor.Exit(lockObj); } }
In C#, we use lock
for thread synchronization. In VB.Net, this is done using the SyncLock
keyword, which prevents other threads from entering the block until the current thread finishes executing it.
Why Use a Static Lock Object?
Using a static lock object is not mandatory, but it is common in multi-threading scenarios. You can use an instance object for locking as well. However, using a static lock object ensures that all threads across instances of the class are synchronized on the same lock, reducing the risk of deadlocks or inconsistent results.
Locking Multiple Objects
If you need to lock multiple objects simultaneously, you can do so by nesting lock
statements.
lock (obj1) { lock (obj2) { // Critical section of code } }
Alternatively, you can combine both locks in one statement for simplicity:
lock (obj1) lock (obj2) { // Critical section of code }
In this article, we explored thread locking in C# using both the lock
statement and the Monitor
class. These mechanisms ensure thread safety by allowing only one thread to access critical sections of code at a time.
- How to fix 'Failure sending mail' in C#
- How to Parse a Comma-Separated String from App.config in C#
- How to convert a dictionary to a list in C#
- How to retrieve the Executable Path in C#
- How to validate an IP address in C#
- How to retrieve the Downloads Directory Path in C#
- C# Tutorial
- Dictionary with multiple values per key in C#