多线程下C#如何保证线程安全?

jopen 5年前

多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题。所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的。 线程安全问题都是由全局变量及静态变量引起的。

为了保证多线程情况下,访问静态变量的安全,可以用锁机制来保证,如下所示:

 1         //需要加锁的静态全局变量   2         private static bool _isOK = false;   3         //lock只能锁定一个引用类型变量   4         private static object _lock = new object();   5         static void MLock()   6         {   7             //多线程   8             new System.Threading.Thread(Done).Start();   9             new System.Threading.Thread(Done).Start();  10             Console.ReadLine();  11         }  12   13         static void Done()  14         {  15             //lock只能锁定一个引用类型变量  16             lock (_lock)  17             {  18                 if (!_isOK)  19                 {  20                     Console.WriteLine("OK");  21                     _isOK = true;  22                 }  23             }  24         } 

需要注意的是,Lock只能锁住一个引用类型的对象。另外,除了锁机制外,高版本的C#中加入了async和await方法来保证线程安全,如下所示:

 1 public static class AsynAndAwait   2  {   3         //step 1    4         private static int count = 0;   5         //用async和await保证多线程下静态变量count安全   6         public async static void M1()   7         {   8             //async and await将多个线程进行串行处理   9             //等到await之后的语句执行完成后  10             //才执行本线程的其他语句  11             //step 2  12             await Task.Run(new Action(M2));  13             Console.WriteLine("Current Thread ID is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);  14             //step 6  15             count++;  16             //step 7  17             Console.WriteLine("M1 Step is {0}", count);  18         }  19   20         public static void M2()  21         {  22             Console.WriteLine("Current Thread ID is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);  23             //step 3  24             System.Threading.Thread.Sleep(3000);  25             //step 4  26             count++;  27             //step 5  28             Console.WriteLine("M2 Step is {0}", count);  29         }  30 }

在时序图中我们可以知道,共有两个线程进行交互,如下图所示:

用async和await后,上述代码的执行顺序为下图所示:

若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时对一个变量执行读写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

来自: http://www.cnblogs.com/isaboy/p/C_async_await_lock_safe_thread_multi.html