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() 方法执行的结果如下: