標籤:class blog code http com art
C#中的lock語句是怎麼回事,有什麼作用?
C#中的lock語句將lock中的語句塊視為臨界區,讓多線程訪問臨界區代碼時,必須順序訪問。他的作用是在多線程環境下,確保臨界區中的對象只被一個線程操作,防止出現對象被多次改變情況。
注意的地方有:lock對象必須是一個不可變對象,否則無法阻止另一個線程進入臨界區。最好是private static readonly 或者private static。常見的lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 都是不合理的寫法。
原因:
1.lock(this),主要問題是如果類為執行個體化類,那麼this也只是當前執行個體,不能起到鎖定的作用,而且即使是靜態類可以被鎖定,那麼由於尺寸問題,不如鎖定不可變小對象合算。
2.lock(typeof())問題在於鎖定物件類型當相於鎖定類型中的靜態對象部分,鎖定了所有執行個體,速度慢;另一方面,有可能程式其他部分在訪問該對象,已經替您鎖定,將導致您鎖定語句的掛起。原文(Here‘s why: Since there‘s one type object for all instances of a class, it would appear that locking it would provide a lock equivalent to locking a static object contained in your class. You would lock all instances of the class, wait until other threads were done accessing any part of any instance, then lock access so you could access static members safely and without another thread interfering.)
3.lock("")問題在於微軟將內容相同的字串視為同一個對象,如果您在此鎖定了他,那麼其實是鎖定了同一個對象,將阻止其他地方對字串的鎖定。
lock語句的一個典型應用就是單例模式。 而單例模式的一個最簡單實現方式就是用靜態對象方式。如下:
public class ABicycle { private static ABicycle aBicycle = new ABicycle(); public ABicycle Instance() { return aBicycle; }}
這是實現單例模式最簡單的一種方式,但是有一個缺點就是假如ABicycle類被提前調用後,aBicycle即被執行個體化,沒法做到執行個體化延遲。在此情況下,利用一個關聯類別可以避免此問題的發生。即:
public class ABicycle { public ABicycle Instance() { return ABicycleStance.Instance(); } } private class ABicycleStance { internal static readonly ABicycle aBicycle = new ABicycle(); public ABicycle Instance() { return aBicycle; } }
單例模式的一個思路是利用C#的lock語句實現。 最簡單實現方式為:
if(... == null){ ... = new ... } return ...;
如果這樣實現,有一個問題無法迴避,即無法確保只能讓一個線程使對象執行個體化,因為有可能多個線程並發執行到此,同時執行個體化了對象。為此,需要引用lock語句。引用的方式也有講究,最直接的實現方式就是:
private static readonly locker = new object(); //或者這樣寫也可以。 //private static locker = new object(); lock(locker) { if(.. == null) { ... } }
上面做法可行,但是有一個問題是每次返回時首先要對locker上鎖,這樣就犧牲了一些本來不必犧牲的效能,因此,可以修改為以下做法:
private static readonly locker = new object();if(.. == null) { lock(locker) { if(... == null) { } } }
這樣,對於多線程來說是安全的,而且不必每次加鎖,只有在判斷對象沒有執行個體化時加鎖,避免了效能上的損失。
參考資料:
http://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
http://hi.baidu.com/benzhan/item/6304481419d6360dd1d66dff
http://bytes.com/topic/c-sharp/answers/249277-dont-lock-type-objects