Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You need to understand what <code>Pulse</code>, <code>PulseAll</code>, and <code>Wait</code> are doing. The <code>Monitor</code> maintains two queues: the waiting queue and the ready queue. When a thread calls <code>Wait</code> it is moved into the waiting queue. When a thread calls <code>Pulse</code> it moves <em>one and only one</em> thread from the waiting queue to the ready queue. When a thread calls <code>PulseAll</code> it moves <em>all</em> threads from the waiting queue to the ready queue. Threads in the ready queue are eligible to reacquire the lock at any moment, but only after the current holder releases it of course.</p> <p>Based on this knowledge it is fairly easy to understand why you must recheck the queue count when using <code>PulseAll</code>. It is because <em>all</em> dequeueing threads will eventually wake and will want to attempt to extract an item from queue. But, what if there is only one item in the queue to begin with? Obviously, we must recheck the queue count to avoid dequeueing an empty queue.</p> <p>So what would be the conclusion if you had used <code>Pulse</code> instead of <code>PulseAll</code>? There would still be a problem with the simple <code>if</code> check. The reason is because a thread from the ready queue is not necessarily going to be the next thread to acquire the lock. That is because the <code>Monitor</code> does not give preference to a <code>Wait</code> call above an <code>Enter</code> call.</p> <p>The <code>while</code> loop is a fairly standard pattern when using <code>Monitor.Wait</code>. This is because pulsing a thread does not have semantic meaning by itself. It is only a signal that the lock state has changed. When threads wake up after blocking on <code>Wait</code> they should recheck the same condition that was originally used to block the thread to see if the thread can now proceed. Sometimes it cannot and so it should block some more.</p> <p>The best rule of thumb here is that if there is doubt about whether to use an <code>if</code> check or a <code>while</code> check then always choose a <code>while</code> loop because it is safer. In fact, I would take this to the extreme and suggest to <em>always</em> use a <code>while</code> loop because there is no inherent advantage in using the simpler <code>if</code> check and because the <code>if</code> check is almost always the wrong choice anyway. A similar rule holds for choosing whether to use <code>Pulse</code> or <code>PulseAll</code>. If there is doubt about which one to use then always choose <code>PulseAll</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload