2011-10-20 157 views
3

我有一些如下所示的代碼。這是否會造成死鎖?創建死鎖

private readonly object objectLock = new object(); 

public void MethodA() 
{ 
    lock(objectLock) 
    { 
     MethodB(); 
    } 
} 

public void MethodB() 
{ 
    lock(objectLock) 
    { 
     //do something 
    } 
} 

UPDATE:將有2個線程運行

回答

5

不是它的僵局。它在相同的同步對象上鎖定相同的線程。線程可以採用嵌套鎖。它只需要釋放它等於沒有。的時代。

+0

如果MethodA兩次調用MethodB會怎麼樣?那還會好嗎? – Jon

+0

是的,它仍然可以。你試過了嗎?死鎖會掛起你所有涉及到死鎖的線程。單線程不能產生死鎖。你甚至在你的應用中有多個線程? –

+0

對不起,更新了我的問題。有2個線程 – Jon

3

不,你需要兩個鎖定對象,以使陷入僵局。

+3

和兩個線程; p –

+0

對不起,我打算添加到有2個線程的問題。 – Jon

10

沒有 - 但是這將是:

private readonly object objectLockA = new object(); 
private readonly object objectLockB = new object(); 

public void MethodA() 
{ 
    lock(objectLockA) 
    { 
    lock(objectLockB) 
    { 
     //... 
    } 
    } 
} 

public void MethodB() 
{ 
    lock(objectLockB) 
    { 
    lock(objectLockA) 
    { 
     //do something 
    } 
    } 
} 

如果調用並行兩種方法(從2級不同的線程),那麼你會得到一個僵局...

3

如果這是唯一的互斥涉及,它不是。同一個線程可以多次鎖定相同的互斥鎖,只要它解鎖相同的次數即可。

調用MethodA產生相同的線程上的操作順序如下:

  • objectLock
  • 致電MethodB
  • objectLock
  • 解鎖objectLock
  • 退出MethodB
  • 解鎖objectLock

所以,objectLock被鎖定兩次,兩次unlocaked,但沒有僵局:

  • 如果另一個線程試圖調用MethodA它只會在第一鎖合阻擋,但不會死鎖。
  • 如果調用MethodB,也會發生同樣的情況。
  • 如果第一個線程調用MethodB,然後其他線程調用MethodA,則會再次發生「正常」阻塞,但不會發生死鎖。