根据这本在线书籍,volatile
C# 中的关键字不能防止重新排序写操作后跟读操作。它给出了这个例子,其中a
和b
最终都可以设置为0
,尽管x
和y
是volatile
:
class IfYouThinkYouUnderstandVolatile
{
volatile int x, y;
void Test1() // Executed on one thread
{
x = 1; // Volatile write (release-fence)
int a = y; // Volatile read (acquire-fence)
...
}
void Test2() // Executed on another thread
{
y = 1; // Volatile write (release-fence)
int b = x; // Volatile read (acquire-fence)
...
}
}
这似乎符合 10.5.3 中规范所说的内容:
对易失性字段的读取称为易失性读取。易失性读取具有“获取语义”;也就是说,它保证在指令序列中对内存的任何引用之前发生。
对易失性字段的写入称为易失性写入。易失性写入具有“释放语义”;也就是说,它保证发生在指令序列中写指令之前的任何内存引用之后。
这是什么原因?是否存在我们不介意对写入-读取操作进行重新排序的用例?