"c#: The complete referece" book writes "microsoft says that lock is precisely equivalent to Monitor.Enter()/Exit()", but in the following case, they seem to differ in their behaviour.
Please verify whether the following observation is correct or not:
________________
public void fun()
{
Monitor.Enter(x);
Console.WriteLine("Locked X");
Thread.Sleep(100);
x=y;
Monitor.Exit(x);
Console.WriteLine("Released X");
Monitor.Enter(y);
Console.WriteLine("Locked Y");
Thread.Sleep(500);
Monitor.Exit(y);
Console.WriteLine("Released X");
}
__________________
In the above function let x,y be some objects.
I started 2 threads on the same funtion fun().
Now both of these threads will try to lock "x" (the delay is deliberately inserted to achieve
this). Now only one of them will suceed. But the thread that succeeded will change the x to point to y, and then release the lock on the new "x" (which is now y). The first thread that was waiting will never acquier the lock on the original "x", becoz the it will never be signalled by any thread.
The o/p coincides with my observation.
<output of the program>
Locked X
Released X
Locked Y
Released Y
<and the program hangs>
_________________
Now replace the Monitr.Enter(x)/Exit(x) statements with lock(x) statement and
Monitor.Enter(y)/Exit(y) with lock(y). In this case, when the first thread releases the lock on "x", both the threads enter CS, becoz both x & y now point to same object. ie even though the object is same, both the threads are able to acquire locks on it thru different references at the same time.
<output of the program>
Locked X
Locked X
Released X
Locked Y
Released X
Locked Y
Released Y
Released Y
as we can observe when the first thred released "X", the second thread succeeded in lock(x). the first thread then succeeded in lock(y), eventhough both x and y point to the same object.
__________
is it the case that, monitor locks the object refered to by "x" whereas "lock" locks the variable "x"
Can somebody pls give me more details
--------------------------------
From: vasudeva enjamuri
www.cse.iitb.ac.in/vasudeva

Inconsistency between Monitor And Lock
Awsok
_______________________________________________
yes coming to the x,y objects they can be any objects, say some global objects initialized as
x=new Object();
y=new Object();
and the threads are simple threads that execute this function:
(new Thread(new ThreadStart(fun))).Start();
(new Thread(new ThreadStart(fun))).Start();
2 threads are started.
Ahoapap
with regards
RicardoJB
There is a minor detail missing from the "is precisely equivalent" statement - the argument is only evaluated once...
Best regards,
Johan Stenberg
From the C# language specification at http://msdn.microsoft.com/library/default.asp url=/library/en-us/csspec/html/vclrfcsharpspec_8_12.asp:
The
lockstatement obtains the mutual-exclusion lock for a given object, executes a statement, and then releases the lock.The expression of a
lockstatement must denote a value of a reference-type. No implicit boxing conversion (Section 6.1.5) is ever performed for the expression of alockstatement, and thus it is a compile-time error for the expression to denote a value of a value-type.A
lockstatement of the formwhere
xis an expression of a reference-type, is precisely equivalent toSystem.Threading.Monitor.Enter(x); try {...} finally { System.Threading.Monitor.Exit(x); }>> except that
xis only evaluated once. <<While a mutual-exclusion lock is held, code executing in the same execution thread can also obtain and release the lock. However, code executing in other threads is blocked from obtaining the lock until the lock is released.
The
System.Typeobject of a class can conveniently be used as the mutual-exclusion lock for static methods of the class. For example:class Cache { public static void Add(object x) { lock (typeof(Cache)) {
...} } public static void Remove(object x) { lock (typeof(Cache)) {...} } }