VOOZH about

URL: https://www.geeksforgeeks.org/c-sharp/thread-safety-and-race-conditions-in-c/

⇱ Thread Safety and Race Conditions in C# - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Thread Safety and Race Conditions in C#

Last Updated : 20 Apr, 2026

In multithreaded applications, multiple threads often access shared resources such as variables, collections, or files. If this access is not controlled properly, it can lead to inconsistent or unexpected results, a problem known as a race condition. To avoid this, developers write thread-safe code so that shared resources behave predictably even under concurrent access.

What is a Race Condition?

A race condition occurs when two or more threads try to access and modify a shared resource simultaneously without proper synchronization. The outcome depends on the order in which threads execute, which makes the program’s behavior unpredictable.

Example:

Possible Outputs:

Final Count: 1567

or

Final Count: 2000

Explanation:

  • The count++ operation is not atomic, consisting of multiple steps (read, increment, write).
  • If two threads execute simultaneously, one thread’s update may overwrite the other, producing inconsistent results.

What is Thread Safety?

Thread safety means that shared data can be accessed by multiple threads without causing inconsistent results. A thread-safe code ensures predictable behavior regardless of how many threads execute it concurrently.

  • Thread-safe code prevents race conditions.
  • It guarantees consistent results regardless of thread scheduling.
  • Thread safety can be achieved through atomic operations, immutable data, or concurrent collections.

Immutable objects are inherently thread-safe because their state cannot change after creation, eliminating race conditions.

Techniques to Achieve Thread Safety

C# provides multiple ways to make code thread-safe and avoid race conditions.

1. Using lock Keyword


Output
Final Count: 2000

The lock statement ensures that only one thread executes the critical section at a time, preventing race conditions.

2. Using Interlocked Class

The Interlocked class provides atomic operations for thread-safe updates without using locks.


Output
Final Count: 2000

3. Using Mutex

Mutex is used when synchronization is needed across multiple processes as well as threads.


Output
Final Count: 2000

4. Using Thread-Safe Collection

Concurrent collections (like ConcurrentDictionary or ConcurrentQueue) provide built-in thread safety and reduce the need for explicit synchronization.


Output
Items in queue: 1000
Comment
Article Tags:
Article Tags:

Explore