6
    private const int Total = 500000;
    private static volatile int _count = 0;

    private static void Main()
    {
        Task task = Task.Factory.StartNew(Decrement);
        for (int i = 0; i < Total; i++)
        {
            _count++;
        }

        task.Wait();
        Console.WriteLine(_count);

        Console.ReadLine();
    }

    private static void Decrement()
    {
        for (int i = 0; i < Total; i++)
        {
            _count--;
        }
    }

有时结果为 0,有时结果为 -xxxxxx。我不知道为什么。谁能解释一下并告诉我正确的用法。

4

2 回答 2

5

volatile保证不重新排序操作并禁用缓存优化,但不保证线程安全 - 因此您可以获得从 0 到的任何结果-Total(如果每对--++正确混合)。我在回答为什么以下 C# 多线程代码不输出零虽然它在调试器中输出?.

volatile当您希望其他人修改值时很有用,因此您的代码始终读取合理的最新值,这也将是一致的(即,对于 ++,您将不会int由 0xffff 的高部分和 (0xffff+1) 的低部分组成 -你会得到一个或另一个),因为 volatile 仅适用于以原子方式编写的类型。

如果您想在 2 个线程中修改计数器 - 使用Interlocked.Increment/ Interlocked.Decrement

于 2012-12-11T06:52:51.757 回答
3

volatile不保证线程安全,正如 Alexei Levenkov 的回答中所述。您可以使用System.Threading.Interlocked.

之后,您的示例将如下所示:

    private const int Total = 500000;
    private static volatile int _count = 0;

    private static void Main()
    {
        Task task = Task.Factory.StartNew(Decrement);
        for (int i = 0; i < Total; i++)
        {
            System.Threading.Interlocked.Increment(ref _count);
        }

        task.Wait();
        Console.WriteLine(_count);

        Console.ReadLine();
    }

    private static void Decrement()
    {
        for (int i = 0; i < Total; i++)
        {
            System.Threading.Interlocked.Decrement(ref _count);
        }
    }
于 2012-12-11T06:59:56.293 回答