多執行緒程式設計相對於單執行緒會出現一個特有的問題,就是執行緒安全的問題。所謂的執行緒安全,就是如果你的程式碼所在的行程中有多個執行緒在同時運行,而這些執行緒可能會同時運行這段程式碼。如果每次執行結果和單執行緒運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的。 線程安全性問題都是由全域變數及靜態變數引起的。
為了確保多執行緒情況下,存取靜態變數的安全,可以用鎖定機制來保證,如下所示:
#//需要加鎖的靜態全域變數
private static bool _isOK = false; //lock只能锁定一个引用类型变量 private static object _lock = new object(); static void MLock() { //多线程 new System.Threading.Thread(Done).Start(); new System.Threading.Thread(Done).Start(); Console.ReadLine(); } static void Done() { //lock只能锁定一个引用类型变量 lock (_lock) { if (!_isOK) { Console.WriteLine("OK"); _isOK = true; } } }
要注意的是,Lock只能鎖住一個引用型別的物件。另外,除了鎖定機制外,高版本的C#中加入了async和await方法來保證線程安全,如下所示:
public static class AsynAndAwait { //step 1 private static int count = 0; //用async和await保证多线程下静态变量count安全 public async static void M1() { //async and await将多个线程进行串行处理 //等到await之后的语句执行完成后 //才执行本线程的其他语句 //step 2 await Task.Run(new Action(M2)); Console.WriteLine("Current Thread ID is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId); //step 6 count++; //step 7 Console.WriteLine("M1 Step is {0}", count); } public static void M2() { Console.WriteLine("Current Thread ID is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId); //step 3 System.Threading.Thread.Sleep(3000); //step 4 count++; //step 5 Console.WriteLine("M2 Step is {0}", count); } }
在時序圖中我們可以知道,共有兩個執行緒進行交互,如下圖所示:
用async和await後,上述程式碼的執行順序為下圖所示:
# 若每個執行緒中對全域變數、靜態變數只有讀取操作,而無寫操作,一般來說,這個全域變數是執行緒安全的;若有多個執行緒同時對一個變數執行讀寫入操作,一般都需要考慮執行緒同步,否則就可能影響執行緒安全性
以上是分享多線程下C#如何保證線程安全的詳細內容。更多資訊請關注PHP中文網其他相關文章!