I was looking at Example 2 on this msdn page about Thread synchronization with Monitor.Pulse().
A Cell object is created and passed to both the producer and the consumer objects.
Cell cell = new Cell( );
CellProd prod = new CellProd(cell, 20);
CellCons cons = new CellCons(cell, 20);
A thread is created for each of those two
Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
The ThreadRun in each case being a loop that calls Cell.ReadFromCell() or Cell.WriteToCell() depending on consumer/producer. For example, the producer does this
public void ThreadRun( )
{
for(int looper=1; looper<=quantity; looper++)
cell.WriteToCell(looper); // "producing"
}
The bit I don’t understand is that in each of these methods they start with a
lock(this)
And since it was the same Cell object (ie, the ‘this’ in the above lock statement) passed to both, I would have thought that only one thread could be in this section of code at a time. Yet from Monitor.Pulse() and Monitor.Wait() code that follows it looks like both threads are in those sections at the same time. If one had the lock and hit a Monitor.Wait() then the other thread could never Pulse because it is blocked waiting for the lock.
I’m guessing there is a simple solution and I have misunderstood something, from my tests with running the code it looks like both threads are in their critical sections at the same time, so the lock(this) isn’t doing what I was under the impression it should do.
The thing you’re missing is that
Monitor.Wait(this)will release the lock onthisuntil it’s woken up. So yes, your consumer thread looks like it’s in the lock and therefore owns it, but really it’s temporarily released it.From the docs: