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

volatileAlexei 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 に答える