Correct way to use Random in multithread applicati

2019-01-13 20:35发布

问题:

This question already has an answer here:

  • Is C# Random Number Generator thread safe? 11 answers

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?

回答1:

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();
    }
}


回答2:

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)



回答3:

I think what you want is threadstatic

[ThreadStatic]
static Random rnd=new Random();

int Rand()
{
    if ( rnd == null ) 
    {
       rnd = new Random()
    }
    //Now each thread gets it's own version
    return rnd.Next();
}

That way each thread get their own version of your rnd property

The reason your locking will increase cpu usage is because all threads will wait on that single point (should only be an issue if you use it a lot)

[Update] i fixed the initialization. As someone pointed out it does leave the fact that if you start multiple threads in the same milisecond then they will produce the same results.



回答4:

My group recently looked into this. We came to the conclusion that we should use a random number generator that has been specifically designed to support parallel computing. Tina's Random Number Generator Library (http://numbercrunch.de/trng/) has a stable implementation, and a manual with a theoretical introduction and references to the relevant literature. So far, we are very satisfied with it.



标签: c# random