You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `volatile` keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons. Fields that are declared `volatile` are excluded from certain kinds of optimizations. There is no guarantee of a single total ordering of volatile writes as seen from all threads of execution. For more information, see the <xref:System.Threading.Volatile> class.
15
15
16
+
> [!CAUTION]
17
+
> The `volatile` keyword is often misunderstood and misused in multithreaded programming. In most scenarios, you should use safer and more reliable alternatives instead of `volatile`. Modern .NET provides better concurrency tools like the <xref:System.Threading.Interlocked> class, the [`lock`](../statements/lock.md) statement, or higher-level synchronization primitives. These alternatives provide clearer semantics and stronger guarantees than `volatile`. Consider using `volatile` only in rare, advanced scenarios where you fully understand its limitations and have verified it's the appropriate solution.
18
+
16
19
> [!NOTE]
17
20
> On a multiprocessor system, a volatile read operation does not guarantee to obtain the latest value written to that memory location by any processor. Similarly, a volatile write operation does not guarantee that the value written would be immediately visible to other processors.
18
21
@@ -27,8 +30,21 @@ The `volatile` keyword can be applied to fields of these types:
27
30
28
31
Other types, including `double` and `long`, cannot be marked `volatile` because reads and writes to fields of those types cannot be guaranteed to be atomic. To protect multi-threaded access to those types of fields, use the <xref:System.Threading.Interlocked> class members or protect access using the [`lock`](../statements/lock.md) statement.
29
32
33
+
For most multithreaded scenarios, even with supported types, prefer using <xref:System.Threading.Interlocked> operations, [`lock`](../statements/lock.md) statements, or other synchronization primitives instead of `volatile`. These alternatives are less prone to subtle concurrency bugs.
34
+
30
35
The `volatile` keyword can only be applied to fields of a `class` or `struct`. Local variables cannot be declared `volatile`.
31
36
37
+
## Alternatives to volatile
38
+
39
+
In most cases, you should use one of these safer alternatives instead of `volatile`:
40
+
41
+
-**<xref:System.Threading.Interlocked> operations**: Provide atomic operations for numeric types and reference assignments. These are generally faster and provide stronger guarantees than `volatile`.
42
+
-**[`lock` statement](../statements/lock.md)**: Provides mutual exclusion and memory barriers. Use for protecting larger critical sections.
43
+
-**<xref:System.Threading.Volatile> class**: Provides explicit volatile read and write operations with clearer semantics than the `volatile` keyword.
44
+
-**Higher-level synchronization primitives**: Such as <xref:System.Threading.ReaderWriterLockSlim>, <xref:System.Threading.Semaphore>, or concurrent collections from <xref:System.Collections.Concurrent>.
45
+
46
+
The `volatile` keyword doesn't provide atomicity for operations other than assignment, doesn't prevent race conditions, and doesn't provide ordering guarantees for other memory operations. These limitations make it unsuitable for most concurrency scenarios.
47
+
32
48
## Example
33
49
34
50
The following example shows how to declare a public field variable as `volatile`.
@@ -52,3 +68,6 @@ With the `volatile` modifier added to the declaration of `_shouldStop` in place,
0 commit comments