views:

1421

answers:

3

Will the following code result in a deadlock using C# on .NET?

 class MyClass
 {
    private object lockObj = new object();

    public void Foo()
    {
        lock(lockObj){ 
             Bar();
        }
    }

    public void Bar()
    {
        lock(lockObj){ 
          // Do something 
        }
    }       
 }
+14  A: 

No, not as long as you are locking on the same object. The recursive code effectively already has the lock and so can continue.

This is because lock(object) {...} is shorthand for using the Monitor class. As Marc points out, Monitor allows re-entrancy thus this will work.

If you start locking on different objects, that's when you have to be careful to avoid deadlocks. Especially if you're not acquiring the them in the same sequence.

One further note, your example isn't technically recursive. For it to be recursive, Bar() would have to call itself, typically as part of an iteration.

Here is one good webpage describing thread synchronisation in .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

Neil Barnwell
Especially in different sequences.
Marc Gravell
Re recursion; indeed; for Guy's benefit, the term is re-entrant
Marc Gravell
Thanks for the clarification on the terminology - I've edited and corrected the question.
Guy
+4  A: 

Well, Monitor allows re-entrancy, so you can't deadlock yourself... so no: it shouldn't do

Marc Gravell
+1  A: 

If a thread is already holding a lock, then it will not block itself. The .Net framework ensures this. You only have to make sure that two threads do not attempt to aquire the same two locks out of sequence by whatever code paths.

The same thread can aquire the same lock multiple times, but you have to make sure you release the lock the same number of times that you aquire it. Of course, as long as you are using the "lock" keyword to accomplish this, it happens automatically.

Jeffrey L Whitledge
Note that that's true for monitors, but not necessarily other kinds of lock.
Jon Skeet
(Not wishing to imply that you didn't know that, of course - just that it's an important distinction :)
Jon Skeet
That's a good point. I was actually going to change "lock" to "monitor" throughout, but then I got distracted. And lazy. And the behavior is also true for Windows mutex kernal objects, so I figured, close enough!
Jeffrey L Whitledge