Reputation: 13864
I have the following class
class Program
{
static Random _Random = new Random();
static void Main(string[] args)
{
...
for (int i = 0; i < no_threads; ++i)
{
var thread = new Thread(new ThreadStart(Send));
thread.Start();
}
...
}
static void Send()
{
...
int device_id = _Random.Next(999999);
...
}
}
The code creates the specified number of threads, starts each one, and assigns each thread a random device_id
. For some reason, the first two threads that are created often have the same device_id
. I can't figure out why this happens.
Upvotes: 10
Views: 4733
Reputation: 1500635
Note: The most appropriate approach as of .NET 6 would be to use Random.Shared which is thread-safe.
Random is not thread-safe - you shouldn't be using the same instance from multiple threads. It can get much worse than just returning the same data - by using it from multiple threads, you can get it "stuck" in a state where it will always return 0, IIRC.
Obviously you don't just want to create a new instance for each thread at roughly the same time, as they'll end up with the same seeds...
I have an article which goes into the details of this and provides an implementation which lazily instantiates one instance of Random
per thread using an incrementing seed.
Upvotes: 30
Reputation: 6834
Your example code only shows one use of _Random
per thread. Assuming this is the case, you could also generate the random number in the main for
loop and pass the random number into each thread as a parameter.
for (int i = 0; i < no_threads; ++i)
{
var thread = new Thread(new ThreadStart(Send));
thread.Start(_Random.Next(999999));
}
and then modify your thread function to accept the parameter:
static void Send(int device_id)
{
...
//int device_id = _Random.Next(999999);
...
}
Upvotes: 2
Reputation: 1038830
Random is a pseudo-random number generator and there's nothing preventing it from returning same result for multiple calls. After all there's a probability for this happening. Not to mention that according to the documentation:
Any instance members are not guaranteed to be thread safe.
So you shouldn't be calling the Next method at all from multiple threads.
Upvotes: 5