monitor

K

Kovan Akrei

Hi,
I have a question on regard to Monitor.Enter(..) and Monitor.Exit(..)
I'll start with an example :

public class test{
private static Queue q = new Queue();

public method testMonitor(){

lock(q){
// do some operations on q
Monitor.Enter(this); // lock this object
}

// do some work
Monitor.Exit(this); // Release the lock on this object.
// do some more work
}
}

My question is whether Monitor.Enter (this) will survive the lock(q)
statement and "this" will still be locked for other objects to access it
until we reach and finish executing Monitor.Exit(this).
What if I call Monitor.Exit(..) in another method. Will it still work?

Regards from
Kovan Akrei
 
N

Nicholas Paldino [.NET/C# MVP]

Kovan,

Here is the order for what is happening:

1) The call to Monitor.Enter is made as a result of the lock statement. We
will call this lock A.
2) The call to Monitor.Enter is made as a result of the statement
"Monitor.Enter(this)". This is lock B.
3) lock A is released. This is the result of exiting the lock statement.
4) Lock B is released.

Now, another function can call Exit on the Monitor class, passing in
"this", but the call must come in on the same thread that the call to Enter
was made on.

If you had locked on this for both calls to Enter, this is what the
order of events would have been:

1) The call to Monitor.Enter is made as a result of the lock statement. We
will call this lock A.
2) The call to Monitor.Enter is made as a result of the statement
"Monitor.Enter(this)". This is lock B.
3) lock B is released. This is the result of exiting the lock statement.
4) Lock A is released.

And this is a very dangerous situation to be in.

Hope this helps.
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi Kovan,

Yes it will survive, but you have chances for deadlock.
This code is the same as
public class test{
private static Queue q = new Queue();

public method testMonitor(){
try {
Monitor.Enter(q);
// do some operations on q
Monitor.Enter(this); // lock this object
} finally
{
Monitor.Exit(q);
}

// do some work
Monitor.Exit(this); // Release the lock on this object.
// do some more work
}
}



Now imagine thayou have two threads:
1. The first thread executes this code. it locks(g) at the same time the
second thread locks the object referenced by *this* (I'll call it 'obj')
lock(obj)
then the first thread tries lock(this) which is equvalent to lock(obj) and
it blocks. Now if the second thread tries lock(q) it leads to deadlock.
 
K

Kovan Akrei

Stoitcho Goutsev (100) said:
Hi Kovan,

Yes it will survive, but you have chances for deadlock.
This code is the same as
Monitor.Enter(this)?



Now imagine thayou have two threads:
1. The first thread executes this code. it locks(g) at the same time the
second thread locks the object referenced by *this* (I'll call it 'obj')
lock(obj)
This situation wont happen beacause the second thread already owns the lock
on q. The first thread have to wait until the second thread calls
Monitor.Exit(q).

What I realy wanted to know was what is the status of the lock on "this" (as
a result of Monitor.Enter(this)) after executing the finally statement
(look at the comments inside the code segment).

Kovan
 
K

Kovan Akrei

Nicholas Paldino said:
Kovan,

Here is the order for what is happening:

1) The call to Monitor.Enter is made as a result of the lock statement. We
will call this lock A.
2) The call to Monitor.Enter is made as a result of the statement
"Monitor.Enter(this)". This is lock B.
3) lock A is released. This is the result of exiting the lock statement.
4) Lock B is released.

Do you mean that Lock B is realesed at a result of a call to
Monitor.Exit(this) or as a result of exiting the lock statement?
1) The call to Monitor.Enter is made as a result of the lock statement. We
will call this lock A.
2) The call to Monitor.Enter is made as a result of the statement
"Monitor.Enter(this)". This is lock B.
3) lock B is released. This is the result of exiting the lock statement.
4) Lock A is released.

And this is a very dangerous situation to be in.
I know :)
Hope this helps.
This was a great I'm still a litte bit confused

Kovan
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Kovan Akrei said:
Hi,
I have a question on regard to Monitor.Enter(..) and Monitor.Exit(..)
I'll start with an example :

public class test{
private static Queue q = new Queue();

public method testMonitor(){

lock(q){
// do some operations on q
Monitor.Enter(this); // lock this object
}

// do some work
Monitor.Exit(this); // Release the lock on this object.
// do some more work
}
}

My question is whether Monitor.Enter (this) will survive the lock(q)
statement and "this" will still be locked for other objects to access it
until we reach and finish executing Monitor.Exit(this).
What if I call Monitor.Exit(..) in another method. Will it still work?

Regards from
Kovan Akrei
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi Kovan,
This situation wont happen beacause the second thread already owns the lock
on q. The first thread have to wait until the second thread calls
Monitor.Exit(q).

That scenario was when the second thread executes different code and first
calls lock(obj) and then lock(q). Anyways, It might be not possible in your
code, but is possible in general. Good practice is to avoid those
situations.
What I realy wanted to know was what is the status of the lock on "this" (as
a result of Monitor.Enter(this)) after executing the finally statement
(look at the comments inside the code segment).

After the finally block the thread still owns the lock on *this*. Releasing
the lock on*q* won't release the lock on *this*
 
K

Kovan Akrei

a result of Monitor.Enter(this)) after executing the finally statement
After the finally block the thread still owns the lock on *this*. Releasing
the lock on*q* won't release the lock on *this*
So another thread wont be able to access "this" under the thread that has
the lock on "this" releases it by calling Monitor.Exit(this)?

Kovan
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi Kovan,
That means that if a thread executes the code between the points of
Monitor.Enter(this) and Monitor.Exit(this) and if in that period of time
another thread tries to call Monitor.Enter(obj) (where *obj* is reference to
the same object which *this* for the previous thread refers to) the second
thread will be block until the first thread passes over Monitor.Exit(this)
point.
 
K

Kovan Akrei

How about this situation:
We have to threads th1 and th2 which are going to execute the following
code:

public class Test{
private static Queue queue = new Queue();

public void testMonitor(){

lock( queue ){
// Insert this object into the queue
queue.Enqueue(this);
Monitor.Enter(this); // lock this object
}
// the first thread th1 gets here and gets stopped by the OS. th2
gets controll
Monitor.Exit(this); // Release the lock on this object.
// do some more work
}

public static Test accessQueue(){
lock( queue){
if (queue.Count > 0)
return (Test) queue.Dequeue(); // The second thread th2 get
here
else
return null;
}
}
}

The first thread th1 executes the method testMonitor() and gets as far as
realeasing the lock on queue. Right there the OS stops th1 and resumes th2.
thread th2 executes the method accessQueue(). When th2 get access to queue
there is only one object (this) in the queue.
My question is :
Since th1 owns the lock on "this" at the time when th2 runs and executes the
code inside accessQueue(). Will queue return "this" to th2 as a result to
call to Dequeue? If so will th2 get access to the returned object ("this" )?

Best regards
Kovan
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi Kovan,

Th2 will return the object form Dequeue operation. This is because it tries
lock on queue object which is unlocked and it goes thru.

The fact that one uses a reference to an object as lock object doesn't mean
that no other therad can use that object's members. Threads are mutually
blocked only if they use the same object in the lock statement.
 
K

Kovan Akrei

Hi Stoitcho,
Ofcourse, ofcourse. You are right. Here is another not so stupid question
:).
Could you please take a look at my other posting (posted today) about
bitmasking threadstates to check whether a thread has been started or not?

Thanks in advance.

Kovan

Stoitcho Goutsev (100) said:
Hi Kovan,

Th2 will return the object form Dequeue operation. This is because it tries
lock on queue object which is unlocked and it goes thru.

The fact that one uses a reference to an object as lock object doesn't mean
that no other therad can use that object's members. Threads are mutually
blocked only if they use the same object in the lock statement.

--
B\rgds
100 [C# MVP]

Kovan Akrei said:
How about this situation:
We have to threads th1 and th2 which are going to execute the following
code:

public class Test{
private static Queue queue = new Queue();

public void testMonitor(){

lock( queue ){
// Insert this object into the queue
queue.Enqueue(this);
Monitor.Enter(this); // lock this object
}
// the first thread th1 gets here and gets stopped by the OS. th2
gets controll
Monitor.Exit(this); // Release the lock on this object.
// do some more work
}

public static Test accessQueue(){
lock( queue){
if (queue.Count > 0)
return (Test) queue.Dequeue(); // The second thread th2 get
here
else
return null;
}
}
}

The first thread th1 executes the method testMonitor() and gets as far as
realeasing the lock on queue. Right there the OS stops th1 and resumes th2.
thread th2 executes the method accessQueue(). When th2 get access to queue
there is only one object (this) in the queue.
My question is :
Since th1 owns the lock on "this" at the time when th2 runs and executes the
code inside accessQueue(). Will queue return "this" to th2 as a result to
call to Dequeue? If so will th2 get access to the returned object ("this" )?

Best regards
Kovan

time
the
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top