System.Threading.Interlocked

Namespace: System.Threading
Assembly: System.Runtime.dll

Provides methods that support an ordered, thread-safe way to update data that is shared by multiple threads. These methods are implemented using hardware atomic instructions, where possible.

Methods

Add

public static long Add(ref long location1, long value)
Atomically adds two 64-bit unsigned integers and stores the result in the first location.
Parameters
  • location1: A reference to the first 64-bit unsigned integer to be added.
  • value: The 64-bit unsigned integer to add to location1.
Returns
  • The value that was in location1 before the addition.

Example


long counter = 0;
long increment = 10;

// Atomically add increment to counter
long previousValue = Interlocked.Add(ref counter, increment);

Console.WriteLine($"Previous value: {previousValue}"); // Output: Previous value: 0
Console.WriteLine($"Current value: {counter}");      // Output: Current value: 10
                

CompareExchange

public static object CompareExchange(ref object location1, object value, object comparand)
Atomically compares two references for equality and, if they are equal, replaces the first reference with the second reference and returns the original first reference.
Parameters
  • location1: The reference to compare and swap.
  • value: The new reference to assign to location1 if the comparison is equal to comparand.
  • comparand: The reference to compare with the contents of location1.
Returns
  • The original reference in location1.

Example


object original = "Hello";
object newValue = "World";
object comparand = "Hello";

object result = Interlocked.CompareExchange(ref original, newValue, comparand);

Console.WriteLine($"Original value: {result}"); // Output: Original value: Hello
Console.WriteLine($"New value: {original}");   // Output: New value: World

// Example where comparand does not match
original = "Hello";
comparand = "Goodbye";
result = Interlocked.CompareExchange(ref original, newValue, comparand);

Console.WriteLine($"Original value: {result}"); // Output: Original value: Hello
Console.WriteLine($"New value: {original}");   // Output: New value: Hello
                

Decrement

public static int Decrement(ref int location)
Atomically decrements the specified variable by one.
Parameters
  • location: A reference to the variable to be decremented.
Returns
  • The value that results from decrementing the location parameter.

Example


int counter = 5;

int previousValue = Interlocked.Decrement(ref counter);

Console.WriteLine($"Previous value: {previousValue}"); // Output: Previous value: 5
Console.WriteLine($"Current value: {counter}");      // Output: Current value: 4
                

Exchange

public static int Exchange(ref int location1, int value)
Atomically sets the specified variable to the specified value and returns the original value.
Parameters
  • location1: A reference to the variable to be replaced.
  • value: The value to which the variable is set.
Returns
  • The original value of location1.

Example


int counter = 10;
int newValue = 25;

int originalValue = Interlocked.Exchange(ref counter, newValue);

Console.WriteLine($"Original value: {originalValue}"); // Output: Original value: 10
Console.WriteLine($"New value: {counter}");         // Output: New value: 25
                

Increment

public static int Increment(ref int location)
Atomically increments the specified variable by one.
Parameters
  • location: A reference to the variable to be incremented.
Returns
  • The value that results from incrementing the location parameter.

Example


int counter = 5;

int previousValue = Interlocked.Increment(ref counter);

Console.WriteLine($"Previous value: {previousValue}"); // Output: Previous value: 5
Console.WriteLine($"Current value: {counter}");      // Output: Current value: 6
                

Read

public static long Read(ref long location)
Atomically reads the value from the specified variable.
Parameters
  • location: A reference to the variable to read.
Returns
  • The value read from location.

Example


long value = 100L;

long readValue = Interlocked.Read(ref value);

Console.WriteLine($"Read value: {readValue}"); // Output: Read value: 100