开发者

Why the following C# multi-threaded code does not output zero though it does in debugger?

class Program
{
    private static volatile int value;

    public static void Increment()
    {
        for (int i =0; i <100000; i++)
        {
            value++;
        }
    }

    public static void Decrement()
    {
  开发者_如何学JAVA      for (int j =0 ; j < 100000; j++)
        {
            value--;
        }
    }

    public static void ThreadTest()
    {
        value = 0;

        var incrementThread = new Thread(Increment);

        var decrementThread = new Thread(Decrement);

        incrementThread.Start();

        decrementThread.Start();

        incrementThread.Join();

        decrementThread.Join();

        Console.WriteLine("Value of value {0}", value);
    }

    static void Main(string[] args)
    {
        ThreadTest();
    }
}


Because it is not supposed to... ++ and -- are not atomic operations (unlike Interlocked.XXXX opreations - Interlocked.Increment).

If you write down each step of ++ and -- and see how both can be intermixed by different threads you'll see why:

increment

1: load value to temp
2: add temp, 1
3: store temp to value

decrement

4: load value to temp2
5: substruct temp2, 1
6: store temp2 to value

So if order is 1,2,3,4,5,6 you get value = 0; but if order is 1,2,4,5,6,3 you get value = 1.


Only trying to make the things simpler... I fought this issue back in the day as well :D

Volatile ensure you read the latest value, and when you write all threads see that new value (and that is what volatile operations are for), but it doesn't ensure that between the read and the write, other thread is not going to modify the value. In the other hand, Interlocked (that provides atomic operations) does ensure it.

Volatile operations are good, when for example a thread or threads read and other modify. For example if you have a volatile Boolean _disposed flag in your class, so if one thread dispose it, it's marked as disposed for all threads straight away.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜