C# lock 關鍵字的一些理解
C# lock 關鍵字的一些理解
問題1:誰是鎖?
lock 這個關鍵字,並不是“鎖”,真正的“鎖”是那個被lock的Object類型的“對象”,請註意,這裏為“對象”加了雙引號著重強調被lock的是對象類型。
問題2:這個鎖有什麽用?
舉個例子,多數商場廁所的蹲位都是小單間型的,也就是一次只能進去一個人,商如何確保每次只能進去一個人呢?不就是一個人進去之後順手把門鎖上麽?這樣你在裏面幹啥事,外邊的人也只能等待你解放完了,才能進入。以此類推,某個 object 對象被lock之後,lock這個對象的那個線程就擁有了執行lock()後面{}的完整的獨立執行權,完整且獨立的執行,不可分割的執行,也就是說,{}是一塊臨界代碼段。
看下面代碼
private static object objlock = new object(); lock (objlock) { //這裏要做一些事情 }
根據問題1的答案進行推導,objlock才是那把鎖,lock 一下,當前線程就獲得了緊跟在lock後面的{}的獨立使用權,在此期間,其他誰都得等著擁有objlock鑰匙的線程執行完之後才能使用{}裏面的代碼。
更專業一點的說法是:在.Net中,每個對象都有一個與之關聯的鎖,對象可以得到並釋放它以便在任意時間只有一個線程可以訪問對象實例變量和方法。同樣.Net中的每一個對象都可以提供一個允許自己進入等待狀態的機制。上面提到的獨立使用權,就是對象的互斥鎖。(關於這個說法,求證無果,只是從博客中找到的,msdn上沒找到相關說法)。
問題3.為什麽只能lock引用類型?
因為只有引用類型才有互斥鎖,如果強行lock值類型,c#會把值裝箱成引用類型,下一次再lock,還會裝箱,這兩次裝箱實際上是裝成了兩個箱子,就不是用一個內存區間了,所以鎖的概念就沒有意義。
問題4.避免lock public類型的對象是為什麽?
還是以廁所為例子吧,私有就好比,這把鎖只有你能訪問到,而且最好這把鎖不會因為外力而有所改變,別人訪問不到,這樣才能保證你進去了,別人就進不去了,如果是公有的,就好比你蹲位小單間的鎖不是安裝在裏面而是安裝在外邊的,別人想不想進就不是你所能控制的了,這樣也不安全。
問題5.下面代碼中_dic到底能不能被其他線程操作?
private static Dictionary<int, BoKwdCueItem> _dic=new Dictionary<int, BoKwdCueItem>(); static object _obj = new object(); lock (_obj) { ///對_dic的寫操作 }
個人理解上 _dic 存在被其他線程修改的可能。
private static Dictionary<int, BoKwdCueItem> _dic=new Dictionary<int, BoKwdCueItem>(); static object _obj = new object(); lock (_obj) { ///對_dic的寫操作 } public void AddToDic(int data) { _dic.Add(data); }
假設A線程執行到lock(_obj)的{}的一半的時候,B線程獲取的CPU的使用權,然後B線程調用了AddToDic方法,就會修改_dic的數據。
以上內容為網上搜集與個人理解,我也不保證一定對。
C# lock 關鍵字的一些理解