1.避免鎖定public類型對象。
如果執行個體可以被公用訪問,將出現lock(this)問題。
如有一個類MyClass,該類有一個Method方法通過lock(this)來實現互斥:
1 public class MyClass
2 {
3 public void Method()
4 {
5 lock(this)
6 {
7 ......
8 }
9 }
10 }
如果一個MyClass的執行個體在不同線程中執行Method方法,可以實現互斥。但如果多個MyClass的執行個體分別在不同的線程中執行Method方法,互斥將失效,因為此處的lock(this)僅對當前的執行個體對象進行了加鎖。
2.禁止鎖定類型
lock(typeof(ClassName))鎖定範圍更為廣泛,由於一個類的所有執行個體都只有一個類型對象(該對象是typeof的返回結果),鎖定它,就鎖定了該對象的所有執行個體。微軟現在建議(原文請參考:http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/SDaskgui06032003.mspx?mfr=true)不要使用lock(typeof(ClassName))。以下的微軟的原文描述:
首先鎖定類型對象是個很緩慢的過程,並且類中的其他線程、甚至在同一個應用程式定義域中啟動並執行其他程式都可以訪問該類型對象,因此,它們就有可能代替您鎖定類型對象,完全阻止您的執行,從而導致你自己的代碼的掛起。
這裡的基本問題是,您並未擁有該類型對象,並且您不知道還有誰可以訪問它。總的來說,依靠鎖定不是由您建立、並且您不知道還有誰可以訪問的對象是一種很不好的做法。這樣做很容易導致死結。
3.禁止鎖定字串
鎖住一個字串更為神奇,只要字串內容相同,就能引起程式掛起。
在.NET中,字串會被暫時存放,如果兩個變數的字串內容相同的話,.NET會把暫存的字串對象分配給該變數。所以如果有兩個地方都在使用lock("my lock")的話,它們實際鎖住的是同一個對象。
如何正確使用lock呢?
微軟給出的建議是:只鎖定私人對象。
範例程式碼:
1 public class MyClass
2 {
3 private static Object somePrivateStaticObject = new Object();
4
5 // methods of class go here--can lock somePrivateStaticObject
6 public void Method()
7 {
8 lock(somePrivateStaticObject)
9 {
10 ......
11 }
12 }
13 }
鎖定私人對象的好處:
首先,類以外的任何代碼都無法鎖定MyClass.somePrivateStaticObject,因此避免了許多死結的可能。由於死結屬於那種最難找到根源的問題,因此,避免發生死結的可能是一件很好的事情。
其次,應用程式中只有一份MyClass.somePrivateStaticObject的副本,並且系統上啟動並執行其他每個應用程式也只有一個副本。因此,在同一個應用程式定義域中的應用程式之間沒有相互影響。