Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can lock and monitor be used on same object safely?

I have the following situation: I want to mutualy exclude access to an object.

So far I normaly would use a lock object

object lockObject = new object();
...

method1: lock(lockObject) { CODE1 }

Now I have also a method which can be called from another thread. It should not be blocked for unknown time, instead it should give an answer in a defined time.

In this case i would use a monitor, like

method2:
try{
   Monitor.TryEnter(lockObject , 20000, ref lockTaken);
   if (lockTaken) {CODE2}
}
catch(...){...}
finally
{
   if (lockTaken) Monitor.Exit(timerLock);
}

Now my question is: can lock and monitor be mixed in such a way if the lockobject is the same and mutually exclude each other, or would it be needed to change every lock to a monitor.

So would both times the same token be "locked", or would the monitor create another token for the object then the lock?

At a glimpse I cannot see that the aplication runs in code of both at the same time. But I don't know if any timing issues can exist, where CODE1 and CODE2 are executed in parallel.

like image 825
Offler Avatar asked Jan 17 '13 10:01

Offler


2 Answers

can lock and monitor be mixed in such a way if the lockobject is the same and mutually exclude each other

Yes, that is totally safe and it will work.

The lock { } statement is rewritten to calls to Monitor.Enter() and Monitor.Exit(). It's just short-hand, very similar to the using() {} statement.

From MSDN:

 lock (x) ...

becomes

System.Threading.Monitor.Enter(x);
try {
   ...
}
finally {
   System.Threading.Monitor.Exit(x);
}

And as per the comment, in Fx4 and later it can use Monitor.TryEnter() . But the simple version above answers your question.

like image 70
Henk Holterman Avatar answered Sep 21 '22 08:09

Henk Holterman


lock (sync)
{
   return World();
}

Would look along the lines of this in Intermediate Language.

L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
L_000c: call int32 Hello::World()
L_0011: stloc.0 
L_0012: leave.s L_001b
L_0014: ldloc.1 
L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object)

So it should be okay. They are technically equivalent.

like image 28
Science_Fiction Avatar answered Sep 25 '22 08:09

Science_Fiction