首頁  >  文章  >  後端開發  >  分享多線程下C#如何保證線程安全

分享多線程下C#如何保證線程安全

Y2J
Y2J原創
2017-04-17 16:43:192430瀏覽

多執行緒程式設計相對於單執行緒會出現一個特有的問題,就是執行緒安全的問題。所謂的執行緒安全,就是如果你的程式碼所在的行程中有多個執行緒在同時運行,而這些執行緒可能會同時運行這段程式碼。如果每次執行結果和單執行緒運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的。 線程安全性問題都是由全域變數及靜態變數引起的。

  為了確保多執行緒情況下,存取靜態變數的安全,可以用鎖定機制來保證,如下所示:

#//需要加鎖的靜態全域變數

 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);
        }
}

在時序圖中我們可以知道,共有兩個執行緒進行交互,如下圖所示:

分享多線程下C#如何保證線程安全

用async和await後,上述程式碼的執行順序為下圖所示:

分享多線程下C#如何保證線程安全

# 若每個執行緒中對全域變數、靜態變數只有讀取操作,而無寫操作,一般來說,這個全域變數是執行緒安全的;若有多個執行緒同時對一個變數執行讀寫入操作,一般都需要考慮執行緒同步,否則就可能影響執行緒安全性

以上是分享多線程下C#如何保證線程安全的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn