B
Bruce Wood
Maybe it's just late in my day, but I'm reading Jon's article on
threading, in particular how to use Monitor.Wait() and Monitor.Pulse(),
and there's something that's not sinking in. The code in question
looks like this:
public class ProducerConsumer
{
readonly object listLock = new object();
Queue queue = new Queue();
public void Produce(object o)
{
lock (listLock)
{
queue.Enqueue(o);
if (queue.Count==1)
{
Monitor.Pulse(listLock);
}
}
}
public object Consume()
{
lock (listLock)
{
while (queue.Count==0)
{
Monitor.Wait(listLock);
}
return queue.Dequeue();
}
}
}
What I don't understand is why the code in the Consume() method is
enclosed in a lock (listLock)? Won't this create a deadlock? I.e.:
Consume acquires a lock on listLock, then calls Monitor.Wait to wait
for a pulse. Produce() then attempts to produce something, but gets
stuck waiting on its "lock (listLock)" test, waiting for Consume() to
release its lock on listLock, which, of course, it will never do,
because it's waiting for Produce() to pulse it.
I know that Jon runs tests his own code so I know that this works,
but I can't see how it could work.
Could someone please explain?
threading, in particular how to use Monitor.Wait() and Monitor.Pulse(),
and there's something that's not sinking in. The code in question
looks like this:
public class ProducerConsumer
{
readonly object listLock = new object();
Queue queue = new Queue();
public void Produce(object o)
{
lock (listLock)
{
queue.Enqueue(o);
if (queue.Count==1)
{
Monitor.Pulse(listLock);
}
}
}
public object Consume()
{
lock (listLock)
{
while (queue.Count==0)
{
Monitor.Wait(listLock);
}
return queue.Dequeue();
}
}
}
What I don't understand is why the code in the Consume() method is
enclosed in a lock (listLock)? Won't this create a deadlock? I.e.:
Consume acquires a lock on listLock, then calls Monitor.Wait to wait
for a pulse. Produce() then attempts to produce something, but gets
stuck waiting on its "lock (listLock)" test, waiting for Consume() to
release its lock on listLock, which, of course, it will never do,
because it's waiting for Produce() to pulse it.
I know that Jon runs tests his own code so I know that this works,
but I can't see how it could work.
Could someone please explain?