2010-02-23 35 views
8

有什麼用什麼傳遞給鎖關鍵字?

void MethodName() 
{ 
    lock(this) 
    { 
     // (...) 
    } 
} 

private object o = new object(); 
void MethodName() 
{ 
    lock(o) 
    { 
     // (...) 
    } 
} 

之間的差額(如果有的話)?

性能有差異嗎?樣式?行爲?

回答

11

區別在於任何人都可以鎖定您的實例,但只有您可以鎖定私人對象。

這有助於防止死鎖。

例如:

比方說,微軟在Control類使用lock(this)

然後,如果其他人鎖定了一個Control實例,他的鎖將阻止Control中的代碼運行,這不是他想要的。

這是特別不好,如果你lock on types that are shared across AppDomains

+0

約薄弱的身份鎖好聽點。 –

17

lock(this)將在「當前」對象鎖定。

鎖定「this」通常是一個壞主意,因爲它將鎖暴露給其他代碼;我希望有一個只讀場,就像這樣:

public class Foo 
{ 
    private readonly object padlock = new object(); 

    public void SomeMethod() 
    { 
     lock(padlock) 
     { 
      ... 
     } 
    } 
} 

這樣,所有的呼叫,SomeMethod(和其他任何在Foo其鎖定在padlock)會鎖定在同一個顯示器上的Foo相同的實例,但沒有否則會通過鎖定在該監視器上而受到干擾

在現實中,除非你正在處理的「流氓」的代碼,這是不可能的其他代碼居然就參考了Foo實例鎖,但它是封裝的問題。

+1

我想補充一點,這樣做的真正優勢不僅在於阻止流氓(或無能)的代碼使你死鎖,而且還允許打包。您可以將鎖定對象公開爲SyncLock屬性,或公開您要打包的對象的SyncLock屬性。這樣,包裝實例上的鎖就成爲包裝實例上的鎖。 –

+0

'掛鎖'似乎缺少一個類型聲明。 – Dan

+0

@Dan:修正,謝謝。 –

1

有一個在範圍的差異,並且可以存在於行爲 (順便說一下,一個區別使用「this」不推薦通過MS

 

// in this case, your lock object is public, so classes outside of this can lock on the same thing 
lock(this) {} 

// in this case, your lock is private, and only you can issue a lock statement against it 
private object lockobj = new object() 
.. 
lock(this.lockobj) {} 

// this one is WRONG -- you willget a new object instance every time, so your lock will not provide mutual exclusion 
void SomeMethod() 
{ 
    // using a local variable for a lock -- wrong 
    object obj = new object(); 
    lock(obj) {} 
} 
 
3

我通常遵循該圖案是這樣的,用於聲明的類static ....

 
public static class SomeClass{ 
    private static object objLock = new object(); 
    .... 
    public static object SomeProperty{ 
     get{ 
      lock(objLock){ 
      // Do whatever needs to be done 
      } 
     } 
     set{ 
      lock(objLock){ 
      } 
     } 
    } 
} 

同樣,對於一個普通的類我會遵循這個模式:

 
public class SomeClass{ 
    private readonly object objLock = new object(); 
    .... 
    public object SomeProperty{ 
     get{ 
      lock(objLock){ 
      // Do whatever needs to be done 
      } 
     } 
     set{ 
      lock(objLock){ 
      } 
     } 
    } 
} 

這樣一來,沒有人可以鎖定我的實例,也防止死鎖的存在的......

編輯:我已經修改了這篇文章,使其與問候的代碼更清晰,其中的基礎static鎖將被使用,併爲一個正常的類...由於史蒂芬達勒爲他們點出局......

+1

你確定你想要一個'靜態鎖嗎? – dalle

+0

@dalle:是的,我會在一個靜態類中使用它,我會在普通類中執行以下操作,'private readonly object objLock = new object()'。這回答了你的問題了嗎? :) – t0mm13b

+0

從您的示例中不清楚您是否處於靜態類。現在你已經指定了這個,它也是有意義的,因爲儲物櫃也是靜態的。您的命名慣例使其更難理解您的意圖,因爲它們違反了.NET標準。 –

相關問題