簡體   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