0
0
CsharpConceptBeginner · 4 min read

What is volatile keyword in C# and How It Works

The volatile keyword in C# tells the compiler that a field can be changed by multiple threads at any time, so it should not cache its value or reorder access. This ensures that every read or write to that field is done directly from memory, helping avoid threading issues.
⚙️

How It Works

Imagine you have a shared whiteboard that multiple people can write on and read from. If one person writes something, everyone else should see the latest message immediately. The volatile keyword in C# works like a rule that says "always check the whiteboard directly" instead of relying on a personal note that might be outdated.

Normally, the computer might keep a copy of a variable in a fast storage area (like a cache) to speed things up. But if multiple threads are changing that variable, these copies can get out of sync. Marking a variable as volatile tells the system to always read and write the actual memory location, so all threads see the latest value.

This helps prevent subtle bugs in programs that run many tasks at once, where one thread might not see changes made by another thread right away.

💻

Example

This example shows a volatile field used to stop a running thread safely by ensuring the latest value is always read.

csharp
using System;
using System.Threading;

class Program
{
    private static volatile bool _stopRequested = false;

    static void Main()
    {
        Thread worker = new Thread(DoWork);
        worker.Start();

        Console.WriteLine("Worker thread started. Press Enter to stop.");
        Console.ReadLine();

        _stopRequested = true; // Signal the worker thread to stop

        worker.Join();
        Console.WriteLine("Worker thread stopped.");
    }

    static void DoWork()
    {
        while (!_stopRequested)
        {
            Console.WriteLine("Working...");
            Thread.Sleep(500);
        }
    }
}
Output
Worker thread started. Press Enter to stop. Working... Working... Working... ... (repeats every 0.5 seconds until Enter pressed) Worker thread stopped.
🎯

When to Use

Use volatile when you have a simple shared variable accessed by multiple threads, and you want to make sure every thread sees the latest value immediately. It is useful for flags or signals like stopping a thread.

However, volatile does not replace full thread synchronization tools like locks when you need to protect complex operations or multiple variables together.

Real-world use cases include:

  • Stopping or pausing threads safely.
  • Simple state flags shared across threads.
  • Lightweight communication between threads without locking.

Key Points

  • Volatile ensures the variable is always read from and written to main memory.
  • It prevents the compiler and CPU from reordering access to that variable.
  • It is mainly for simple flags or signals shared between threads.
  • It does not replace locks or other synchronization for complex data.
  • Use it carefully to avoid subtle threading bugs.

Key Takeaways

Use volatile to ensure a variable is always read fresh from memory in multithreaded code.
volatile is best for simple shared flags or signals, not complex data synchronization.
It prevents caching and reordering of the variable by compiler and CPU.
For complex thread safety, use locks or other synchronization methods instead of volatile.
Marking a variable volatile helps avoid subtle bugs caused by stale or reordered reads/writes.