Random Numbers and Multi-Threading

by Larry Spencer Sunday, July 24, 2011 8:54 AM

File this one under Cute Code.

You are probably aware that the System.Random class has two constructors. You can give it an integer "seed" or you can use the default constructor which seeds the sequence of random numbers based on the system time.

If you want real pseudo-randomness (as opposed to not-random-at all, used for replicable testing), you'll use the default constructor.

But what if you have several threads starting at once and you need a different sequence of random numbers in each? One problem you'll face right away is that the Random class is not thread-safe. That means you can't use the same instance of Random across all your threads. 

If you simply create a new Random object in each thread, chances are good that some of them will start close enough together that they will get the same clock-based initialization.

Here's a cute solution that I stumbled across at http://www.albahari.com/threading/part3.aspx.

var localRandom = new ThreadLocal<Random>
 ( () => new Random (Guid.NewGuid().GetHashCode()) );

Guid.NewGuid() is guaranteed to give you a different Guid every time, and GetHashCode will turn it into the integer you need to seed the Random object. The ThreadLocal class, new in .NET 4.0, lets you easily make a separate, lazy-initialized Random object in each thread.

Cute, eh?

P.S. - For something closer to real randomness, you'd use the RNGCryptoServiceProvicer class. It generates better random numbers, but at a performance cost.


All | General

Add comment

About the Author

Larry Spencer

Larry Spencer develops software with the Microsoft .NET Framework for ScerIS, a document-management company in Sudbury, MA.