title: Is using two lock statements one after another thread safe?
body: <p>I've been learning about multi-thread programming and working on the dining philosophers problem. I'm trying to <strong>cause</strong> a deadlock <strong>without</strong> sleeping any threads. Here is the code snippet that I'm using:</p>
  <pre><code>public class Program
      {
          const int NumberOfPhilosophers = 5;
          const int NumberOfForks = 5;
          const int EatingTimeInMs = 20;
          static object[] forks = new object[NumberOfForks];
          static Thread[] philosopherEatingThreads = new Thread[NumberOfPhilosophers];
  
          public static void Main(string[] args)
          {
              for (int i = 0; i &lt; NumberOfForks; i++)
              {
                  forks[i] = new object();
              }
  
              for (int i = 0; i &lt; NumberOfPhilosophers; i++)
              {
                  int philosopherIndex = i;
  
                  philosopherEatingThreads[i] = new Thread(() =&gt; { DoWork(philosopherIndex); })
                  {
                      Name = philosopherIndex.ToString()
                  };
  
                  philosopherEatingThreads[philosopherIndex].Start();
              }
  
          }
  
          public static void DoWork(int philosopherIndex)
          {
              int fork1Index = philosopherIndex;
              int fork2Index = (philosopherIndex + 1 ) % NumberOfForks;
              var fork1 = forks[fork1Index];
              var fork2 = forks[fork2Index];
  
              lock (fork1)
              {
                  lock (fork2)
                  {
                      Thread.Sleep(EatingTimeInMs);
                  }
              }
          }
      }
  </code></pre>
  <p>I wasn't able to see any deadlocks after trying a couple of times. I know that not experiencing a deadlock <strong>does not</strong> mean that this code is thread-safe.
  For example, when I change the lock statement and add latency I cause deadlock.</p>
  <pre><code>lock (fork1)
  {
      Thread.Sleep(10);
      lock (fork2)
      {
          Thread.Sleep(EatingTimeInMs);
      }
  }
  </code></pre>
  <p>I have two questions:</p>
  <ol>
  <li>Is using two lock statements one after another an atomic operation?</li>
  <li>If using Thread.Sleep() causes a deadlock in a code snippet, does that mean that the code snippet is <strong>not</strong> thread-safe?</li>
  </ol>
  <p>Thank you!</p>