Grab a lock automatically without calling the lock(object) strange


T

Tony Johansson

Hi!

Here I have a program that works but I don't really understand how it works
as it does.
This program is using two threads. It's the main thread and a secondary
thread.
When the secondary thread is executing this statement
Monitor.Wait(locker);
in method ConsumeMessage it will release the locker lock and wait until the
main thread is calling the Monitor:pulse.
Now when the main thread is executing this statement
Monitor.Pulse(locker);
it will send a signal to the secondary thread that you have some work to do
now.
the secondary thread will start and grab the locker object but how can it do
so without calling this row
lock (locker) in the method ConsumeMessage.
I have tested this by adding this row
Console.WriteLine("Just before the while loop");
just before the while loop in method ConsumeMessage
and this row is not being executed.

I know the secondary thread will grab the locker object in some way without
calling this row
lock (locker).

So my question is just how is that possible ?

class Program
{
private static bool messageExists = false;
private static readonly object locker = new object();
private static String message = null;

static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(ConsumeMessage));
t.Name = "Consumer thread";
t.Start();
Thread.Sleep(2000);
lock (locker)
{
Console.WriteLine("Producer thread: message produced.");
message = "New message: hi!";
messageExists = true;
Console.WriteLine("Producer thread: about to pulse waiting
threads...");
Monitor.PulseAll(locker);
Thread.Sleep(5000);
}
t.Join();
Console.WriteLine("Press any...");
Console.ReadKey();
}

private static void ConsumeMessage()
{
lock (locker)
{
Console.WriteLine("Just before the while loop");
while (!messageExists)
{
Console.WriteLine(Thread.CurrentThread.Name + " : No
message....hibernating...");
Monitor.Wait(locker);
}
Console.WriteLine(Thread.CurrentThread.Name+"--> Message
consumed: "+message);
}
}
}

//Tony
 
Ad

Advertisements

P

Peter Duniho

Tony said:
Hi!

Here I have a program that works but I don't really understand how it works
as it does.
This program is using two threads. It's the main thread and a secondary
thread.
When the secondary thread is executing this statement
Monitor.Wait(locker);
in method ConsumeMessage it will release the locker lock and wait until the
main thread is calling the Monitor:pulse.
Now when the main thread is executing this statement
Monitor.Pulse(locker);
it will send a signal to the secondary thread that you have some work to do
now.
the secondary thread will start and grab the locker object but how can it do
so without calling this row
lock (locker) in the method ConsumeMessage. [...]

The documentation is quite clear on the question. The Monitor.Wait()
method does not return until it has successfully re-acquired the lock.
This will not happen until the other thread that called Monitor.Pulse()
has released it (e.g. by leaving the "lock (locker) { … }" protected
block of code).

Pete
 

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