title: When ThreadB Monitor.Pulse(_locker) which thread will get _locker first?
body: <p>I read this article <a href="https://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified#_articleTop" rel="nofollow noreferrer">https://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified#_articleTop</a></p>
  <p>There is a quote:</p>
  <blockquote>
  <p>Recommended pattern</p>
  <p>These queues can lead to unexpected behaviour. When a Pulse occurs, the head of the waiting queue is released and is added to the ready queue. However, if there are other threads in the ready queue, they will acquire the lock before the thread that was released. This is a problem, because the thread that acquires the lock can alter the state that the pulsed thread relies on.</p>
  <p>The solution is to use a while condition inside the lock statement:</p>
  <pre><code>readonly object key = new object();
  bool block = true;
  
  // thread A
  lock ( key )
  {
    while ( block )
      Monitor.Wait( key );
    block = true;
  }
  
  // thread B
  lock ( key )
  {
    block = false;
    Monitor.Pulse( key );
  }
  </code></pre>
  </blockquote>
  <p>The author says ThreadC will get _locker first, but in my demo in which I run three threads I find it is not true. ThreadC gets _locker last.</p>
  <p>Here is my code ：</p>
  <pre><code>class Program
  {
      private static readonly object _locker = new object();
      public static void ThreadA()
      {
  
          new Thread(() =&gt;
          {
              lock (_locker)
              {
                  Console.WriteLine(&quot;Thread A acquire lock then wait threadId {0}&quot;, Thread.CurrentThread.ManagedThreadId);
                  Monitor.Wait(_locker);
                  Thread.Sleep(1000);
                  Console.WriteLine(&quot;Thread A  Continue .. threadId {0}&quot;, Thread.CurrentThread.ManagedThreadId);
              }
          }).Start();
              
      }
      public static void ThreadB()
      {
  
          new Thread(() =&gt;
          {
              lock (_locker)
              {
                  Console.WriteLine(&quot;Thread B acquire lock...then pulse  threadId {0}&quot;,Thread.CurrentThread.ManagedThreadId);
                  Monitor.Pulse(_locker);
                  Thread.Sleep(1000);
                  Console.WriteLine(&quot;Thread B sleep...then realse the locker threadId {0}&quot;, Thread.CurrentThread.ManagedThreadId);
              }
          }).Start();
  
      }
  
      public static void ThreadC()
      {
  
          new Thread(ThreadA).Start();
      }
  
      static void Main(string[] args)
      {
  
  
          ThreadA();
  
          Thread.Sleep(10); // ensure threadA get _locker firstly
  
          ThreadB();
  
          ThreadC();
  
  
      }
  }
  </code></pre>