Inconsistency between Volatile and Interlocked

51 views Asked by At

Below is the source code:

public static class Volatile
{
   // ...
   public static ulong Read(ref ulong location);
   public static long Read(ref long location);
   public static double Read(ref double location);  
}

public static class Interlocked
{
   // ... Interlocked has only two Read methods as below:
   public static ulong Read(ref ulong location);
   public static long Read(ref long location);   
}

I have some questions here, why there is no counterpart "Read double" method in Interlocked?

And what's the difference between Volatile's "Read long" with Interlocked's "Read long".

1

There are 1 answers

0
shingo On

Volatile and Interlocked have different functions, so you should not use words like "inconsistency" or "counterpart".

Interlocked.Read

Reading a 64-bit number in a 32-bit program isn't atomic, e.g.

Thread1 Thread2
a = 0x100000002L; long b = a;

In a 32-bit program, you have a certain probability of reading results that have only been updated by half, i.e. 0x100000000L or 2. Interlocked.Read ensures that you can only read 0 or 0x100000002L.

If you are still developing 32-bit programs and you need a Interlocked.Read(double) method, you can use CompareExchange instead:

double d = Interlocked.CompareExchange(ref doubleValue, 0, 0);

Volatile

For statements that read and write data, the compiler or processor may optimize the order of execution to improve memory access efficiency, e.g.

Thread1 Thread2
x1 = 1; y2 = y1;
y1 = 2; x2 = x1;

If you don't use Volatile, you have a chance to see y2 == 2 and x2 == 0, this is because y1 = 2 may have been executed before x1 = 1. So you need to use Volatile to prevent the execution order from being changed.

Thread1 Thread2
Volatile.Write(ref x1, 1); y2 = Volatile.Read(ref y1);
y1 = 2; x2 = x1;