您好,登錄后才能下訂單哦!
本篇內容介紹了“C#怎么使用LOCK實現線程同步”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
線程安全概念:線程安全是指在當一個線程訪問該類的某個數據時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程才可使用。不會出現數據不一致或者數據污染。
線程有可能和其他線程共享一些資源,比如,內存,文件,數據庫等。當多個線程同時讀寫同一份共享資源的時候,可能會引起沖突。這時候,我們需要引入線程“同步”機制,即各位線程之間要有個先來后到,不能一窩蜂擠上去搶作一團。線程同步的真實意思和字面意思恰好相反。線程同步的真實意思,其實是“排隊”:幾個線程之間要排隊,一個一個對共享資源進行操作,而不是同時進行操作。
下面將通過簡單的四個案例進行對比,來講解LOCK的實現線程同步使用。
首先創建兩個線程,兩個線程執行同一個方法,代碼如下:
class Program { static void Main(string[] args) { Thread threadA = new Thread(ThreadMethod); //執行的必須是無返回值的方法 threadA.Name = "threadA"; Thread threadB = new Thread(ThreadMethod); //執行的必須是無返回值的方法 threadB.Name = "threadB"; threadA.Start(); threadB.Start(); Console.ReadKey(); } public static void ThreadMethod(object parameter) { for (int i = 1; i <= 10; i++) { Console.WriteLine("我是:{0},我循環{1}次", Thread.CurrentThread.Name, i); Thread.Sleep(1000);//休眠一秒 } } }
通過下面的執行結果,可以很清楚的看到,兩個線程是在同時執行ThreadMethod這個方法,這顯然不符合我們線程同步的要求。
執行結果:
通過對上面代碼的修改如下:
class Program { static void Main(string[] args) { Program pro = new Program(); Thread threadA = new Thread(pro.ThreadMethod); threadA.Name = "threadA"; Thread threadB = new Thread(pro.ThreadMethod); threadB.Name = "threadB"; threadA.Start(); threadB.Start(); Console.ReadKey(); } public void ThreadMethod(object parameter) { lock (this) //添加lock關鍵字 { for (int i = 1; i <= 10; i++) { Console.WriteLine("我是:{0},我循環{1}次", Thread.CurrentThread.Name, i); Thread.Sleep(1000);//休眠一秒 } } } }
執行結果:
我們通過添加了 lock(this) {...}代碼,查看執行結果實現了我們想要的線程同步需求。
但是我們知道this表示當前類實例的本身,那么有這么一種情況,我們把需要訪問的方法所在的類型進行兩個實例A和B,線程A訪問實例A的方法ThreadMethod,線程B訪問實例B的方法ThreadMethod,這樣的話還能夠達到線程同步的需求嗎?
修改后的代碼如下:
class Program { static void Main(string[] args) { Program pro1 = new Program(); Program pro2 = new Program(); Thread threadA = new Thread(pro1.ThreadMethod); threadA.Name = "threadA"; Thread threadB = new Thread(pro2.ThreadMethod); threadB.Name = "threadB"; threadA.Start(); threadB.Start(); Console.ReadKey(); } public void ThreadMethod(object parameter) { lock (this) //添加lock關鍵字 { for (int i = 1; i <= 10; i++) { Console.WriteLine("我是:{0},我循環{1}次", Thread.CurrentThread.Name, i); Thread.Sleep(1000);//休眠一秒 } } } }
執行結果:
我們會發現,線程又沒有實現同步了!lock(this)對于這種情況是不行的!
通過對上面代碼再次進行如下修改:
class Program { private static object obj = new object(); static void Main(string[] args) { Program pro1 = new Program(); Program pro2 = new Program(); Thread threadA = new Thread(pro1.ThreadMethod); threadA.Name = "threadA"; Thread threadB = new Thread(pro2.ThreadMethod); threadB.Name = "threadB"; threadA.Start(); threadB.Start(); Console.ReadKey(); } public void ThreadMethod(object parameter) { lock (obj) //添加lock關鍵字 { for (int i = 1; i <= 10; i++) { Console.WriteLine("我是:{0},我循環{1}次", Thread.CurrentThread.Name, i); Thread.Sleep(1000);//休眠一秒 } } } }
執行結果:
通過查看執行結果。會發現代碼實現了我們的需求。
那么 lock(this) 和lock(Obj)有什么區別呢?
lock(this) 鎖定 當前實例對象,如果有多個類實例的話,lock鎖定的只是當前類實例,對其它類實例無影響。所有不推薦使用。
lock(typeof(Model))鎖定的是model類的所有實例。
lock(obj)鎖定的對象是全局的私有化靜態變量。外部無法對該變量進行訪問。
lock 確保當一個線程位于代碼的臨界區時,另一個線程不進入臨界區。如果其他線程試圖進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。
所以,lock的結果好不好,還是關鍵看鎖的誰,如果外邊能對這個誰進行修改,lock就失去了作用。所以一般情況下,使用私有的、靜態的并且是只讀的對象
“C#怎么使用LOCK實現線程同步”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。