Правильный способ использования Random в многопоточном приложении
Ok. Вот что я знаю, что не получится:
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();
}
Это будет работать корректно, но если используется несколькими потоками, загрузка процессора идет вверх, чего я не хочу, и который, я думаю, не нужен:
int Rand()
{
lock(rnd)
{
return rnd.Next();
}
}
Итак, существует ли потокобезопасный класс Random для С# или лучший способ его использования?
Ответы
Ответ 1
Я использую что-то вроде этого:
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;
}
(бесстыдно украденный из комментария Jeroen Vannevel)
Ответ 3
Я думаю, что вы хотите использовать threadstatic
[ThreadStatic]
static Random rnd=new Random();
int Rand()
{
if ( rnd == null )
{
rnd = new Random()
}
//Now each thread gets it own version
return rnd.Next();
}
Таким образом, каждый поток получает свою собственную версию вашего свойства rnd
Причина, по которой ваша блокировка увеличит использование процессора, - это то, что все потоки будут ждать в этой единственной точке (это должно быть проблемой, если вы используете ее много)
[Обновление] я исправлена инициализация. Как заметил кто-то, он оставляет тот факт, что если вы начнете несколько потоков в тот же самый milisecond, тогда они будут давать одинаковые результаты.
Ответ 4
Моя группа недавно изучила это. Мы пришли к выводу, что мы должны использовать генератор случайных чисел, специально разработанный для поддержки параллельных вычислений. Библиотека генераторов случайных чисел Тины (http://numbercrunch.de/trng/) имеет стабильную реализацию и руководство с теоретическим введением и ссылками на соответствующую литературу. До сих пор мы очень довольны этим.