5

I am using a single Random instance to rapidly get random numbers in a Parallel query, but I have noticed that, eventually, Random.Next always returns zero. Is there a reason for that?

BrainStorm.exe
  • 1,565
  • 3
  • 23
  • 40

2 Answers2

21

Random isn't thread-safe. You should use a different instance of Random for each thread, instead. I wouldn't suggest locking as you've suggested, as otherwise if that's a significant part of your overall time, it could end up being no faster than running it in a single thread to start with. Instead, you can use a thread local variable to have a separate instance per thread - taking care to ensure that you don't accidentally use the same seed for all the instances, which would give you the same sequence of of numbers in each thread.

See my article on randomness for more details, including sample code.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Good article in the link Jon. Did you consider using the ThreadId to further increase the separation of seed values? – Corey Dec 05 '13 at 23:04
  • @Corey: I'd hope that consecutive seeds don't have any obvious impact on the sequence of random numbers anyway. An alternative is to have a single "master" `Random` instance that *is* guarded by a lock, and use that for the seed of each thread-local random. – Jon Skeet Dec 05 '13 at 23:13
  • I guess I just like adding as much entropy as possible to my seeds. It's probably silly, but something about sequential seed values makes me uneasy :P – Corey Dec 05 '13 at 23:15
0

Random apparently doesn't like being used in several threads at once. Putting a lock around the call like this:

object syncLock = new object();
<snip>
int value;
lock(syncLock){
    value = random.Next();
}

seems to have solved the problem.

BrainStorm.exe
  • 1,565
  • 3
  • 23
  • 40