8

I wrote simple code ( attached ) and i don't understand why the lock on some block is not locking the scope.

The code :

 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 ); } } } 

I expect that the calling for the foo method in the while loop will be waiting until the locker will be release ( locker scope ) - but all the calls of the foo with arg of ++i can enter to the locker block.

3
  • I think its the same thread so shouldn't lock itself (maybe someone knows it in more detail) Commented Apr 11, 2012 at 3:44
  • 1
    i definately learned something new on this one, +1 Commented Apr 11, 2012 at 3:45
  • 12
    If you're already in the bathroom, and the door is already locked, and you put a second lock on the door, you are still in the bathroom already. Commented Apr 11, 2012 at 4:20

4 Answers 4

15

The lock used here is reentrant. It will prevent another thread from entering the monitor, but the thread holding the lock will not be blocked.

Sign up to request clarification or add additional context in comments.

7 Comments

i had no idea that's how it worked - you're 100% on this right?
@Gabriel This is exactly right; the lock statement in C# is re-entrant. You can't lock "yourself" out.
that's not what happens in C/C++, unless my memory is shot (and maybe it is) - just surprising that I never realized such a difference
@Gabriel: C doesn't have a lock statement, though.
@Gabriel: Maybe you used the native mutexes? In Windows, mutexes are recursive. The opposite is true for POSIX systems. For a while this was true in Boost as well (versions prior to 1.35) - boost::mutex was recursive in Windows and non-recursive in POSIX.
|
10

The lock keyword is just syntactic sugar around the Monitor.Enter and Monitor.Exit methods. As seen in the documentation for Monitor:

It is legal for the same thread to invoke Enter more than once without it blocking;

Calling lock(object) from the same thread more than once has no effect other than to increase the lock count.

5 Comments

is there another type of lock that behaves the way the poster expected Monitor/lock to behave?
@Gabriel, you could use AutoResetEvent for that.
@Gabriel SpinLock is not re-entrant, IOW, SpinLonk.Enter will fail if called on the same thread that already holds the lock; the two aren't exactly the same but would have worked as the OP seemed to expect.
@svick AutoResetEvent isn't a lock.
i guess maybe the question is: what scenario would require the same thread to lock itself out of a critical section of code? I can't think of one off the top of my head...
1

Lock doesn't apply if you are on the same thread. See http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

Comments

1

When you make a recursive call here on thread say t1, it is not spinning off a separate thread. The recursive call is being made on the same thread t1.

As t1 is already holding the lock, it does not have to wait for the lock.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.