views:

704

answers:

2

Monitor.PulseAll notifies all waiting threads in the queue.

Monitor.Pulse notifies a thread in the waiting queue. (The next waiting thread)

Only the next Thread (1 Thread) can acquire the lock. So what is the difference? When should i use Pulse and when PulseAll?

+11  A: 

Use PulseAll when you want to wake up multiple threads, because the condition they're waiting for may now be fulfilled for more than one thread. (Waiting is almost always associated with a condition - you should usually be testing that condition in a while loop.)

Use Pulse when you only want to wake up one thread, because only one thread will actually be able to do useful work.

To give two analogies:

Imagine you've got a single printer. Only one person can use it at a time, so if you're got a lot of people waiting, you send them all to sleep - but you only wake one person up when the printer becomes free. This mirrors the use of Pulse.

Now imagine you run a shop. While you're closed, customers wait outside the shop. When you open the shop, you don't just want to wake up one customer - they can all come in now. This mirrors the use of PulseAll.

Jon Skeet
"When the thread that invoked PulseAll releases the lock, the next thread in the ready queue acquires the lock." - if i can only handle one customer a time - why should i wake up everybody?
michl86
*If* you can only handle one customer at a time, you wouldn't. Unless you wanted to let them all browse, and then queue at the checkout to pay...
Jon Skeet
(Very few shops only allow one customer in at a time :)
Jon Skeet
i think now i understand. if i have more worker threads in state "idle" i would use PulseAll to wake up more jobs... (o; thanks!
michl86
+6  A: 

A Monitor has two queues: the waiting queue and the ready queue. In the absence of Wait and Pulse, all threads that try to acquire the lock go into the ready queue. When the lock becomes available, one thread from the ready queue will acquire it.

When a thread acquires the lock and then does a Wait, that thread goes into the waiting queue. It's waiting for a Pulse or PulseAll, and will remain in the waiting queue until it receives a Pulse, even if other threads from the ready queue acquire and release the lock.

Pulse moves one thread from the waiting queue to the ready queue. PulseAll moves ALL threads from the waiting queue to the ready queue.

The key here is that threads in the waiting queue can never acquire the lock. They are waiting for a pulse to move them back to the ready queue so that they can acquire the lock when it becomes available.

There's a reasonably good discussion of Wait and Pulse--at least a bit to get you started--here.

Jim Mischel