首页 > 技术文章 > 多线程相关Interlocked.Increment问题

gw2010 2013-11-29 13:43 原文

 

今天群里有人问到如下代码打印出来的东西为什么不是连续得,所以有大神解释了原因。在这过程中遇到了些奇怪的情况 

        static void Main(string[] args)
        {

            for (int i = 0; i < 10; i++)
            {
                new System.Threading.Thread(Foo).Start();
            }

            //System.Threading.Thread.Sleep(20);
            //Console.WriteLine(num);

            Console.Read();
        }

        static int num = 0;

        static void Foo()
        {
            Console.WriteLine(num);
            Interlocked.Increment(ref num);

        }

 

我第一次想的是这个Interlocked.Increment是原子的增加,多个线程同时访问也不会引起数据的错误 ,所以显示虽然是无序的,但是只要数据不重复就是正常的,我觉得打印出来的数字不会重复。

但是我写下上面代码运行看结果时发现还是有重复的,这是什么情况? 为什么还会重复呢?难道Interlocked.Increment不是原子的操作?因该是只允许一个进程操作,也就是数据不会出错才对。

后来看到Console.WriteLine(num)这里,我才想到,其实显示出来的是Console.WriteLine(num)这里的读取,虽然下面一行增加是能保证只有一个线程操作,但是上面这行不一定,所以显示是有相同的情况?为了确认是否这样,我在是后加上了两行。 

            System.Threading.Thread.Sleep(20);
            Console.WriteLine(num);

 

从这里可以显示出num的最后值,如果过程中操作是有几个线程同时操作的话,这里的数据也不会是10.可以最后显示是10,也就是Interlocked.Increment方法没有问题。

如果要让这相显示正常可以把这两行一起加上lock(){} 这保证。 即然这样那Interlocked.Increment()还有什么用?可能也只有最后查看这个增量标识才有用。

推荐阅读