Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Thread Synchronization in C#
Thread synchronization in C# is essential for coordinating access to shared resources in multithreaded applications. It prevents race conditions and ensures data consistency by controlling how multiple threads access critical sections of code.
C# provides several synchronization mechanisms including the lock statement, Mutex class, and other primitives to manage concurrent thread execution effectively.
Syntax
Following is the syntax for using the lock statement −
lock (syncObject) {
// critical section code
}
Following is the syntax for creating and using a Mutex −
private static Mutex mutex = new Mutex(); mutex.WaitOne(); // acquire lock // critical section mutex.ReleaseMutex(); // release lock
Using Lock Statement for Thread Synchronization
The lock statement ensures that only one thread can execute a block of code at a time. It requires a reference type object as the synchronization target −
Example
using System;
using System.Threading;
public class Counter {
private int count = 0;
private readonly object lockObject = new object();
public void Increment() {
lock (lockObject) {
count++;
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Count = {count}");
Thread.Sleep(100); // Simulate work
}
}
public int GetCount() {
lock (lockObject) {
return count;
}
}
}
public class Program {
public static void Main() {
Counter counter = new Counter();
Thread t1 = new Thread(() => {
for (int i = 0; i {
for (int i = 0; i
The output of the above code is −
Thread 4: Count = 1
Thread 4: Count = 2
Thread 4: Count = 3
Thread 5: Count = 4
Thread 5: Count = 5
Thread 5: Count = 6
Final count: 6
Using Mutex for Cross-Process Synchronization
The Mutex class provides synchronization across process boundaries, unlike the lock statement which only works within a single process −
Example
using System;
using System.Threading;
public class MutexExample {
private static Mutex mutex = new Mutex();
private static int sharedResource = 0;
public static void AccessResource(int threadId) {
Console.WriteLine($"Thread {threadId} waiting for mutex...");
mutex.WaitOne(); // Acquire the mutex
try {
Console.WriteLine($"Thread {threadId} acquired mutex");
sharedResource++;
Console.WriteLine($"Thread {threadId}: Shared resource = {sharedResource}");
Thread.Sleep(1000); // Simulate work
}
finally {
Console.WriteLine($"Thread {threadId} releasing mutex");
mutex.ReleaseMutex(); // Always release in finally block
}
}
public static void Main() {
Thread[] threads = new Thread[3];
for (int i = 0; i AccessResource(threadId));
threads[i].Start();
}
for (int i = 0; i
The output of the above code is −
Thread 1 waiting for mutex...
Thread 2 waiting for mutex...
Thread 3 waiting for mutex...
Thread 1 acquired mutex
Thread 1: Shared resource = 1
Thread 1 releasing mutex
Thread 2 acquired mutex
Thread 2: Shared resource = 2
Thread 2 releasing mutex
Thread 3 acquired mutex
Thread 3: Shared resource = 3
Thread 3 releasing mutex
All threads completed
Comparison of Synchronization Methods
| Feature | Lock Statement | Mutex |
|---|---|---|
| Scope | Single process only | Cross-process synchronization |
| Performance | Faster, lightweight | Slower, heavyweight |
| Automatic cleanup | Yes, automatic release | Manual release required |
| Exception handling | Automatic release on exception | Must use try-finally block |
Conclusion
Thread synchronization in C# is crucial for preventing race conditions in multithreaded applications. Use the lock statement for intra-process synchronization due to its simplicity and performance, while Mutex is ideal when synchronization across multiple processes is required.
