Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Thread.Sleep() inside lock statement in .net

I was wondering if a call to Threa.Sleep on a thread that already acquiered a Monitor will release the lock before going to sleep:

object o = new object();
Montior.Enter(o);
Thread.Sleep(1000);
Monitor.Exit(o);

While the thread is suspended - can other thread acquire o?

like image 514
Pini Salim Avatar asked Feb 26 '12 15:02

Pini Salim


3 Answers

No, the thread won't release the lock before suspending/sleeping

and no other thread will be able to acquire o until the sleeping thread wakes up and releases the locked object

like image 174
Haris Hasan Avatar answered Oct 04 '22 22:10

Haris Hasan


No, between Enter and Exit, no other thread can take the lock whatever you do inbetween.

like image 35
Albin Sunnanbo Avatar answered Oct 04 '22 23:10

Albin Sunnanbo


No, the lock will not be released if you Sleep.

If you want to release it, use Monitor.Wait(o, timeout); further, you can also use this to signal from another thread - another thread can use Monitor.Pulse[All] (while holding the lock) to wake the waiting thread earlier than "timeout" (it will re-acquire the lock in the process, too).

Note that whenever using Enter/Exit, you should consider using try/finally too - or you risk not releasing the lock if an exception happens.

Example:

bool haveLock = false;
try {
    Monitor.Enter(ref haveLock);
     // important: Wait releases, waits, and re-acquires the lock
    bool wokeEarly = Monitor.Wait(o, timeout);
    if(wokeEarly) {...}
} finally {
    if(haveLock) Monitor.Exit(o);
}

Another thread could do:

lock(o) { Monitor.PulseAll(o); }

Which will nudge any threads currently in a Wait on that object (but does nothing if no objects were waking). Emphasis: the waiting thread still has to wait for the pulsing thread to release the lock, since it needs to re-acquire.

like image 40
Marc Gravell Avatar answered Oct 04 '22 23:10

Marc Gravell