Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to use Random in multithread application [duplicate]

Tags:

c#

random

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?

like image 379
Arsen Zahray Avatar asked Oct 09 '13 11:10

Arsen Zahray


People also ask

How to use random in a multithreaded context?

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.

How do I randomize a thread in Java?

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.

Is it safe to use random numbers from multiple threads?

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:

How to generate random values from a thread in Oracle?

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.


2 Answers

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();     } } 
like image 75
Alessandro D'Andria Avatar answered Sep 23 '22 02:09

Alessandro D'Andria


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)

like image 34
Benoit Blanchon Avatar answered Sep 21 '22 02:09

Benoit Blanchon