volatile 和 Interlocked

 

class Volatile_Test3
    {
        private static volatile int count = 0;    

        public static void Test()
        {
            count = 0;
            Task[] tasks = new Task[100];
            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = Task.Run(() =>
                {
                    for (int j = 0; j < 10; j++)
                    {
                        ++count;
                    }
                });
            }
            Task.WaitAll(tasks);
            Console.WriteLine("end ,the count={0}", count);
        }


        public static void Test2()
        {
            count = 0;
            Task[] tasks = new Task[100];
            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = Task.Run(() =>
                {
                    for (int j = 0; j < 10; j++)
                    {
                        Interlocked.Increment(ref count);
                    }
                });
            }
            Task.WaitAll(tasks);
            Console.WriteLine("end ,the count={0}", count);
        }
    }

 

static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Volatile_Test3.Test();
            }
            Console.ReadKey();
        }

 

之前认为,volatile 修饰的变量 执行的是 原子性操作,上述代码 应该显示 1000;实际上:

不是每次都是1000;

参考了网上大神的解释,大概明白了 volatile 的真正意义:它只是保证每个线程读取到的都是最新的值,不会读取到"脏数据"(这里用脏数据不是太准确,小弟是个新手,不知道该用什么词语,暂时代替一下).

而真正的原子性操作应该用 Interlocked 类的一系列静态方法,而且这个类的方法效率很高.

Test2() 方法执行的结果如下:

 

posted @ 2018-12-09 16:12  热敷哥  阅读(449)  评论(0编辑  收藏  举报