2013-12-05 3 views
4

Я использую один случайный экземпляр для быстрого получения случайных чисел в запросе Parallel, но я заметил, что в конечном итоге Random.Next всегда возвращает ноль. Есть ли причина для этого?Random.Next() всегда возвращает 0

+4

Random is * not * гарантированно будет потокобезопасным. – user2864740

+2

[Получение случайных чисел потокобезопасным способом] (http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx) –

+0

Вы говорите, что это случайное время, а затем оседает на ноль? –

ответ

16

Random не является потокобезопасным. Вместо этого вы должны использовать другой экземпляр Random для каждого потока. I не будет предлагать блокировку, как вы предложили, так как в противном случае, если это значительная часть вашего общего времени, она может оказаться не быстрее, чем запустить ее в одном потоке для начала. Вместо этого вы можете использовать локальную переменную потока, чтобы иметь отдельный экземпляр для каждого потока - следя за тем, чтобы вы случайно не использовали одно и то же семя для всех экземпляров, что дало бы вам одну и ту же последовательность чисел в каждом потоке.

См. Мои article on randomness для более подробной информации, включая пример кода.

+0

Хорошая статья в ссылке Jon. Считаете ли вы использование ThreadId для дальнейшего увеличения разделения начальных значений? – Corey

+0

@Corey: Я надеюсь, что последовательные семена не будут иметь никакого очевидного влияния на последовательность случайных чисел. Альтернативой является наличие единственного «ведущего» экземпляра «Случайный», который * * охраняется блокировкой, и использовать это для семени каждого случайного случайного потока. –

+0

Наверное, мне просто нравится добавлять как можно больше энтропии к моим семенам. Это, наверное, глупо, но что-то о последовательных значениях семян делает меня непростым: P – Corey

2

Random, по-видимому, не рекомендуется использовать в нескольких потоках одновременно. Блокировка вокруг вызова выглядит следующим образом:

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

, похоже, решил проблему.

+1

Это пахнет _Coding by Coincidence_. –

+0

@AustinSalonen Я рекомендую вам добавить ссылку на эту статью, это выглядит интересно. –

Смежные вопросы