在 C# 中使用易失性关键字
本文关键字:易失性 关键字 | 更新日期: 2023-09-27 18:34:48
我正在使用 Volatile 关键字,但它的行为与预期有所不同。
这是我的代码
private static volatile int _N = 0;
var up = Task.Run(() =>
{
for (int i = 0; i < 1000000; i++)
_N++;
});
for (int i = 0; i < 1000000; i++)
_N--;
up.Wait();
Console.WriteLine(_N);
_N是一个类变量。
我每次得到的都是不同的数字,就好像没有使用关键字 volatile 一样。这是关键字的正确行为吗?
我每次得到的都是不同的数字,就好像没有使用关键字 volatile 一样。这是关键字的正确行为吗?
将变量指定为易失性不会使递增或递减操作成为原子操作。想象一下,你的循环是这样写的:
for (int i = 0; i < 1000000; i++)
{
int x = _N;
x++;
_N = x;
}
这实际上是上一个循环 - 只是现在更清楚的是你正在阅读,然后执行操作,然后写入。没有什么可以阻止另一个线程在这两个操作之间写入不同的值。
对于原子性,您应该使用 Interlocked.Increment
和 Interlocked.Decrement
。
就个人而言,我会尽量避免使用volatile
。它的确切含义相对难以描述,在我看来也很难推理。最好尽可能使用更高级别的构造。