Monitor.Enter and Monitor.Exit provides exclusive locking and ensures only one thread enters inside monitor block at a time. Lock statement internally uses Monitor.Enter and Monitor.Exit with try/finally block.
public class MyClass
{
static int a=12, b=4;
static object obj =new Object();
public static void Divide()
{
Monitor.Enter(obj);
try {
if (b != 0)
Console.WriteLine("{0} / {1} = {2}", a, b, a/b);
b = 0;
}
finally
{
Monitor.Exit(obj);
}
}
public static void Main()
{
Thread t1 = new Thread(new ThreadStart(Divide));
t1.Start();
}
}
As demonstrated in above code, when one thread enters
Monitor.Enter block, other threads are trying to enter inside block at same time
are queued in ready queue until first thread call Monitor.exit statement
similar to lock statement.
In some scenario with multithreaded application, once
Monitor.Enter acquires lock and due to some exception not able to enter
try/finally block in this case lock will not be released and cause memory
leaked. Dotnet 4.0 has the solution for the same, added overload Monitor.Enter
method. It takes referenced boolean value along with locked object. If lock is
acquired, the overloaded boolean value returns true. Let’s see how it works.
static int a = 12, b = 4;
static object obj = new Object();
static bool isLocked = false;
public static void Divide()
{
Monitor.Enter(obj,ref isLocked);
try
{
if (b
!= 0)
Console.WriteLine("{0} / {1} = {2}", a, b, a / b);
b = 0;
}
finally
{
if
(isLocked)
{
Monitor.Exit(obj);
}
}
}
As per above code if lock is acquired successfully then
isLocked variable's value set to true and we can release lock if isLocked value is true.
If lock is not acquired isLocked value remains false.
See Also -
No comments:
Post a Comment