1

我正在使用 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。这是关键字的正确行为吗?

4

1 回答 1

11

每次我得到的是一个不同的数字,好像没有使用关键字 volatile。这是关键字的正确行为吗?

将变量指定为 volatile 不会使递增或递减操作成为原子操作。想象一下你的循环是这样写的:

for (int i = 0; i < 1000000; i++)
{
    int x = _N;
    x++;
    _N = x;
}

实际上就是之前的循环 - 只是现在更清楚的是您正在阅读,然后执行操作,然后写入。没有什么可以阻止另一个线程在这两个操作之间写入不同的值。

对于原子性,您应该使用Interlocked.Incrementand Interlocked.Decrement

就我个人而言,我会尽量避免使用volatile。在我看来,它的确切含义相对难以描述,也难以推理。最好尽可能使用更高级别的构造。

于 2013-10-10T11:28:49.593 回答