In multithreaded applications, managing access to shared resources is crucial to prevent inconsistent behavior. The C# lock
statement provide thread safety by ensuring that only one thread can execute a critical section at a time. This prevents multiple threads from concurrently accessing shared resources, which could lead to functional issues or incorrect outputs.
The lock
statement acquires a mutual-exclusion lock for an object, executes a block of code, and then releases the lock. While one thread holds the lock, other threads are blocked from acquiring it, ensuring safe access to the shared resource.
It is recommended to use a dedicated lock object instance (e.g., private readonly object _lockObject = new object();
) for each shared resource to avoid potential deadlocks that could arise from using the same lock object for different resources.
Code Example:
using System;
using System.Threading;
class Program
{
private static readonly object _lockObject = new object();
private static int _sharedResource = 0;
static void Main()
{
Thread thread1 = new Thread(IncrementResource);
Thread thread2 = new Thread(IncrementResource);
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine($"Final value of shared resource: {_sharedResource}");
}
static void IncrementResource()
{
for (int i = 0; i < 1000; i++)
{
lock (_lockObject)
{
_sharedResource++;
}
}
}
}
Explanation:
_lockObject
: This is the dedicated lock object used to control access to the shared resource.lock (_lockObject)
: Ensures that only one thread at a time can execute the code inside thelock
block._sharedResource
: A shared variable that multiple threads attempt to modify.
In this example, two threads increment the shared resource 1,000 times each. The lock
statement ensures that increments are done safely without race conditions, leading to a consistent final value of 2,000.
Code Simple!