
4. Synchronization
Synchronization in Multithreading
Multithreading allows multiple threads to execute simultaneously. However, it introduces the issue of multiple threads accessing and modifying shared data at the same time, which leads to data inconsistency. This issue is known as the synchronization problem.
Synchronization Problem
In a multithreaded environment, the synchronization problem occurs when two threads attempt to modify shared data concurrently. This can lead to unexpected and inconsistent results.
Example:
public class Counter {
public int Count = 0;
}
public class ThreadSample {
Counter _counter;
public ThreadSample(Counter counter) {
_counter = counter;
}
public void Count() {
for (int i = 0; i < 10000; i++) {
_counter.Count++;
}
}
}
Without synchronization, if two threads run the Count
method on the same Counter
object, the final Count
value may not be 20000 due to the synchronization problem.
Synchronization Techniques
The solution to the synchronization problem is to isolate the shared data when it is being modified. This can be achieved using various synchronization techniques:
Interlocked Class
The Interlocked
class provides methods for atomic operations, which are performed in a single, unbroken step that cannot be interrupted by other threads.
Example:
public void Count() {
for (int i = 0; i < 10000; i++) {
Interlocked.Increment(ref _counter.Count);
}
}
Monitor Class
The Monitor
class provides a mechanism that synchronizes access to blocks of code. A thread enters the monitor by calling the Monitor.Enter
method and exits it by calling the Monitor.Exit
method. Only one thread can execute inside the monitor at a time.
Example:
public void Count() {
Monitor.Enter(_counter);
try {
for (int i = 0; i < 10000; i++) {
_counter.Count++;
}
} finally {
Monitor.Exit(_counter);
}
}
Lock Keyword
The lock
keyword in C# is a syntactic shortcut for a Monitor.Enter
/ Monitor.Exit
block. It ensures that one thread does not enter a critical section of code while another thread is in the middle of the same code block.
Example:
public void Count() {
lock (_counter) {
for (int i = 0; i < 10000; i++) {
_counter.Count++;
}
}
}
Mutex Class
The Mutex
class is similar to a Monitor
, but it works across multiple processes, meaning it can be used to synchronize threads in different applications. It can be named or unnamed. An unnamed Mutex
is local to the application, while a named Mutex
can be used across the system.
Example:
public class MutexSample {
static Mutex _mutex = new Mutex();
public void Run() {
_mutex.WaitOne();
try {
// Critical section
for (int i = 0; i < 10000; i++) {
_counter.Count++;
}
} finally {
_mutex.ReleaseMutex();
}
}
}
In this example, the Mutex
ensures that only one thread can enter the critical section at a time, even if the threads are from different processes.
Reference
The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:
Original Note - Azerbaijani Version