2012-04-11 153 views
7

我寫了簡單的代碼(附加),我不明白爲什麼某些塊的鎖沒有鎖定範圍。爲什麼這段代碼中的鎖不起作用?

代碼:

object locker = new object(); 
    private void foo(int i) 
    { 
     Console.WriteLine(string.Format("i is {0}", i)); 
     lock(locker) 
     { 
      while(true) 
      { 
       Console.WriteLine(string.Format("i in while loop is {0}", i)) ; 
       foo(++i); 
      } 
     } 
    } 

我希望在while循環foo的方法的調用將等待,直到更衣室會釋放(更衣室範圍) - 但與ARG foo的所有通話++我可以進入儲物櫃。

+0

我認爲它是相同的線程,所以不應該鎖定自己(也許有人更詳細地瞭解它) – V4Vendetta 2012-04-11 03:44:17

+0

我明確瞭解到這個新東西,+1 – 2012-04-11 03:45:37

+11

如果你已經在浴室,門是已經鎖定了,你在門上放了一個*秒*鎖,*你已經在浴室了。* – 2012-04-11 04:20:33

回答

12

這裏使用的鎖是可重入的。它將阻止另一個線程進入監視器,但持有鎖的線程不會被阻塞。

+0

我不知道這是如何工作的 - 你在這個權利100%? – 2012-04-11 03:44:09

+2

@ Gabriel這是完全正確的; C#中的'lock'語句是可重入的。你不能鎖定「你自己」。 – dlev 2012-04-11 03:46:06

+0

這不是在C/C++中發生的情況,除非我的內存被拍攝(也許它是) - 只是令人驚訝,我從未意識到這種差異 – 2012-04-11 03:48:16

7

鎖定關鍵字是圍繞Monitor.EnterMonitor.Exit方法只是語法糖。正如看到的documentationMonitor

是合法的同一個線程調用輸入不止一次沒有它阻塞;

從同一個線程調用lock(object)不止一次除了增加鎖定計數之外沒有任何效果。

+0

是否有另一種類型的鎖,其行爲方式與發佈者期望的監視器/鎖的行爲方式相同? – 2012-04-11 03:50:13

+1

@Gabriel,你可以使用'AutoResetEvent'。 – svick 2012-04-11 12:56:09

+1

@Gabriel'SpinLock'不可重入,IOW,如果在已經擁有該鎖的同一個線程上調用'SpinLonk.Enter'將會失敗;這兩個不完全一樣,但會像OP期望的那樣工作。 – 2012-04-11 20:48:56

1

當你在線程say t1上進行遞歸調用時,它不會旋轉單獨的線程。遞歸調用正在同一個線程t1上進行。

由於t1已經持有鎖,所以不必等待鎖。

相關問題