2011-07-31 70 views

回答

18

可能有很大的差異。兩者之間最大的區別在於第一個示例使用單個對象鎖定(因此static關鍵字),而第二個示例中的this關鍵字意味着鎖定實例。因此,從性能的角度來看,甚至從正確性的角度來看,可能會有很大的差異,但這取決於鎖內的代碼。

當您只需要同步對實例級別字段的訪問權限時,不應使用static關鍵字,因爲它會同步代碼本身,而不是數據(這可能會導致不必要的性能下降)。當然,如果數據本身是靜態的(類級數據而不是實例級數據),則需要使用static關鍵字。另一方面,當您使用this關鍵字鎖定時,當您訪問共享/靜態資源時,您將(當然)有一個正確性問題,因爲同步是基於實例的,並且多個實例仍然能夠同時訪問共享數據。

還有一個問題,但其差異遠小於先前提到的差異。第一個示例使用私有聲明的對象進行鎖定,而另一個使用this指針,該指針是對該實例方法本身的對象的引用。因爲這個引用可以被其他對象公開訪問,所以它們可能會鎖定它,這在極少數情況下會導致死鎖。如果你是一個應用程序開發人員,我不會太擔心這個(只要你不鎖定像System.StringSystem.Type這樣的東西),但是如果你是一個框架開發人員,你肯定不應該使用lock(this),因爲沒有辦法知道應用程序開發人員將如何使用您的代碼。

8

它幾乎總是最好鎖定一個私人只讀對象。

所不同的是this通常到外部代碼,這可能需要一個鎖定在其上,即,可見 -

var obj = new YourClass(); 
lock(obj) 
{ 
    ... 
} 

...在這種情況下YourClasslock (this)內部的任何企圖都將阻止。

1

因爲您不想從對象外部訪問鎖。

如果使用鎖(這個)你可以得到一個僵局:如果你把它不會死鎖對象內部鎖

void blah() { 
    lock(this); 
    sleep(200); 
} 

//Some other block of code 

MyObject a; 
foreach(Mythread m in threads) 
{ 
    lock(a); 
    m.Call(a.blah); //Not the best syntax, but you get the idea. 
}