繁体   English   中英

为什么使用volatile产生不同的结果?

[英]Why does using volatile produce a different result?

    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。 我不知道为什么。 任何人都可以解释它并告诉我正确的用法。

volatile保证不重新排序操作并禁用缓存优化,但不保证线程安全 - 所以你可以得到0到-Total任何结果(如果每对--++正确混合)。 我已经介绍了“preper mixing”以回答为什么下面的C#多线程代码虽然在调试器中没有输出零但是?

当你期望别人修改值时, volatile是有用的,所以你的代码总是读取合理的最近值,这也是一致的(即对于++你不会得到由0xffff的高部分和(0xffff + 1)的低部分组成的int ) - 你会得到一个或另一个)因为volatile只适用于原子写入的类型。

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

如Alexei Levenkov所说, volatile不保证线程安全。 您可以使用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);
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM