title: Using Random in Parallel.For
body: <p>My program performs many simulations, each of which calls for many random numbers to be generated. The serial method is straightforward and works. However, in my pursuit of parallelizing the work I believe I created a more straightforward method than what I could find. The other methods are somewhat dated and something might be possible now that wasn't possible then.</p>
  
  <p>Am I missing something that will make my method susceptible to any of the myriad of multithreading problems? My method uses the ability of a <code>Parallel.For</code> to instantiate a variable for individual thread use and thus it doesn't require another class like the other methods I found. In this case each thread gets its own <code>Random</code>.</p>
  
  <p>Timing: </p>
  
  <p>My method: 4s</p>
  
  <p>Stephen: 14s</p>
  
  <p>Jon: 16s</p>
  
  <p>Clearly I don't know as much as Stephen or Jon so I'm concerned I missed something.</p>
  
  <p>My method:</p>
  
  <pre><code>Random rnd = new Random();
  int trials = 1_000_000;
  
  private readonly object globalLock = new object();
  ParallelOptions po = new ParallelOptions();
  po.MaxDegreeOfParallelism = 4;
  
  await Task.Run(() =&gt;
  {
      Parallel.For&lt;Random&gt;(0, trials, po, 
      () =&gt; { lock(globalLock){ return new Random(rnd.Next()); } }, 
      (i, loop, local) =&gt;
      {
          for (int work = 0; work &lt; 1000; work++)
          {
              local.Next();
          }
  
          return local;
      },
          (x) =&gt; { }
      );
  });
  </code></pre>
  
  <p>This next method is by Stephen Toub on the <a href="https://blogs.msdn.microsoft.com/pfxteam/2009/02/19/getting-random-numbers-in-a-thread-safe-way/" rel="nofollow noreferrer">MSDN Blog</a>:</p>
  
  <pre><code>public static class RandomGen2
  {
      private static Random _global = new Random();
      [ThreadStatic]
      private static Random _local;
  
      public static int Next()
      {
          Random inst = _local;
          if (inst == null)
          {
              int seed;
              lock (_global) seed = _global.Next();
              _local = inst = new Random(seed);
          }
          return inst.Next();
       }
  }
  
  await Task.Run(() =&gt;
  {
      Parallel.For(0, trials, i =&gt;
      {
          for (int work = 0; work &lt; 1000; work++)
          {
              RandomGen2.Next();
          }
      });
  
  });
  </code></pre>
  
  <p>This next method is by Jon Skeet on <a href="https://codeblog.jonskeet.uk/2009/11/04/revisiting-randomness/" rel="nofollow noreferrer">his blog</a>:</p>
  
  <pre><code>public static class ThreadLocalRandom
  {
      private static readonly Random globalRandom = new Random();
      private static readonly object globalLock = new object();
  
      private static readonly ThreadLocal&lt;Random&gt; threadRandom = new ThreadLocal&lt;Random&gt;(NewRandom);
  
      public static Random NewRandom()
      {
          lock (globalLock)
          {
              return new Random(globalRandom.Next());
          }
      }
  
      public static Random Instance { get { return threadRandom.Value; } }
  
      public static int Next()
      {
          return Instance.Next();
      }
  }
  
  await Task.Run(() =&gt;
  {
      Parallel.For(0, trials, i =&gt;
      {
          for (int work = 0; work &lt; 1000; work++)
          {
              ThreadLocalRandom.Instance.Next();
          }
      });
  });
  </code></pre>
  
  <p><strong>Update/answer:</strong> Brian has pointed out that I was using Jon's method incorrectly. A more correct way would be to call an <code>ThreadLocalRandom.Instance</code> for each <code>Parallel.For</code> loop and use that instance for the internal <code>for</code> loop. This prevents the thread check on each call and instead there is only one thread check per <code>Parallel.For</code> loop. Using Jon's method correctly makes his method faster than the overload of <code>Parallel.For</code> that I was using.</p>