Ok. Here is what I know that won't work:
int Rand() { //will return the same number over and over again return new Random().Next(); } static Random rnd=new Random(); int Rand() { //if used like this from multiple threads, rnd will dissintegrate //over time and always return 0 return rnd.Next(); }
This will work correctly, but if used by multiple threads, the CPU usage goes way up, which I don't want, and which I think is not necessary:
int Rand() { lock(rnd) { return rnd.Next(); } }
So, is there a thread-safe Random class for c#, or a better way to use it?
The point of this example is that, in a multithreaded context, you may be creating a Random instance for each iteration, but many iterations across threads are likely to end up with the same value. There are several approaches then one could take in using Random from multiple threads to avoid these kinds of issues. One approach is to use a lock.
Try a ThreadLocal<T>. private static readonly ThreadLocal<Random> rand = new ThreadLocal<Random>(() => new Random()); – Jeroen Vannevel Oct 9 '13 at 11:22 7 @JeroenVannevel: You will probably want to randomize the seeds of the Randominstances, because otherwise threads starting at the same time would get the same sequence of random numbers.
The first is to assume that Random is thread-safe and is ok to be used concurrently from multiple threads. This is a bad idea, and can have some drastic consequences on the quality of the random numbers (degrading them well below the “good enough” bar). For an example of this, consider the following program:
As per the Oracle documentation, we just need to call ThreadLocalRandom.current () method, and it will return the instance of ThreadLocalRandom for the current thread. We can then generate random values by invoking available instance methods of the class.
I use something like this:
public static class StaticRandom { static int seed = Environment.TickCount; static readonly ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed))); public static int Rand() { return random.Value.Next(); } }
readonly ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random(GetSeed())); int Rand() { return random.Value.Next(); } static int GetSeed() { return Environment.TickCount * Thread.CurrentThread.ManagedThreadId; }
(shamelessly stolen from the comment of Jeroen Vannevel)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With