lock與C#多線程多線程
lock 關鍵字將語句塊標記爲臨界區,方法是獲取給定對象的互斥鎖,執行語句,而後釋放該鎖。簡單講就相似於 你去銀行辦理業務,一個櫃檯一次只能操做覺得客戶,而若是你要到這個櫃檯辦理業務就必須等前面的人的業務完成,而彼此之間不會有交集。下面經過具體的代碼來深刻說明: 測試
using System; using System.Threading; namespace LockTest { class Program { static void Main() { Test test = new Test(); Thread one = new Thread(test.ThreadOne); //線程一調用test的 ThreadOne 方法
Thread two = new Thread(test.ThreadTwo); //線程而調用test的 ThreadTwo 方法
one.Start(); //啓動線程一
two.Start(); //啓動線程二
Console.ReadKey(); } } class LockTest { public int Number { get; set; } = 10; public void Print() { Console.WriteLine("The number is " + Number); } } class Test { private readonly LockTest _lockTest = new LockTest(); //用於測試的對象
public void ThreadOne() { //在此方法內鎖定 _lockTest 所引用的對象並執行相應操做,在操做執行完之前不會釋放次對象
lock (_lockTest) { Console.WriteLine("The object has been locked!"); Thread.Sleep(5000); //讓當前線程休眠 5s
_lockTest.Number = 200; Console.Write("ThreadOne: "); _lockTest.Print(); } //操做完成並釋放對象
Console.WriteLine("The object has been released!"); } public void ThreadTwo() {
//Console.WriteLine(_lockTest.Number); _lockTest.Number = 100;
//Console.WriteLine(_lockTest.Number); //鎖定 _lockTest 所引用的對象 //若是要保證 lock 正常工做,全部對 _lockTest 的操做都要使用 lock 鎖定 //好比上面 _lockTest.Number=100; 在 lock 外面,那麼它將不受約束(便可以強制訪問 _lockTest) //若是在上面語句後加 Console.WriteLine(_lockTest.Number); 那麼將輸出 100 而不是 200 (也不是 10)
lock (_lockTest) {
//_lockTest.Number=100; Console.Write("ThreadTwo: "); _lockTest.Print(); } } } }
運行上面的代碼會發如今ThreadTwo 方法裏的 lock內的代碼 時有明顯的延遲,即必須等到ThreadOne運行完成了才繼續執行 lock內部的代碼,並且輸出的結果是200而不是100,說明 lock 外面的代碼不會發生任何延遲。若是把 _lockTest.Number=100; 語句放在lock內部,會發現結果變成了 100 。 ui
經過上面的例子能夠看出要保證 lock 正確工做,要對每一個 _lockTest 的操做加上 lock鎖定 。而在程序運行的時候,會根據線程訪問次對象的前後順序來爲每一個線程排序,且只有排在前面的線程對對象的操做完成了後面的對象才能訪問此對象。
spa