【发布时间】:2011-02-12 09:56:24
【问题描述】:
我正在使用 .NET 创建一个人工生命程序,并且我正在使用在 Singleton 中定义的 C# 的伪随机类。这个想法是,如果我在整个应用程序中使用相同的随机数生成器,我可以只保存种子,然后从种子重新加载以重新计算某个有趣的运行。
public sealed class RandomNumberGenerator : Random
{
private static readonly RandomNumberGenerator instance = new RandomNumberGenerator();
RandomNumberGenerator()
{
}
public static RandomNumberGenerator Instance
{
get
{
return instance;
}
}
}
我还想要一种可以给我两个不同随机数的方法。
public static Tuple<int, int> TwoDifferentRandomNumbers(this Random rnd, int minValue, int maxValue)
{
if (minValue >= maxValue)
throw new ArgumentOutOfRangeException("maxValue", "maxValue must be greater than minValue");
if (minValue + 1 == maxValue)
return Tuple.Create<int, int>(minValue, maxValue);
int rnd1 = rnd.Next(minValue, maxValue);
int rnd2 = rnd.Next(minValue, maxValue);
while (rnd1 == rnd2)
{
rnd2 = rnd.Next(minValue, maxValue);
}
return Tuple.Create<int, int>(rnd1, rnd2);
}
问题是有时rnd.Next(minValue,maxValue总是返回minValue。如果我此时断点并尝试创建一个双精度并将其设置为rnd.NextDouble(),它将返回 0.0。有人知道为什么会这样吗?
我知道它是一个伪随机数生成器,但坦率地说,我没想到它会锁定为 0。随机数生成器正在从多个线程访问......这可能是问题的根源吗?
编辑:谢谢,问题最终是线程安全。
这是新版本的课程。
public sealed class RandomNumberGenerator : Random
{
private static Random _global = new Random();
[ThreadStatic]
private static Random _localInstance;
RandomNumberGenerator()
{
}
public static Random Instance
{
get
{
Random inst = _localInstance;
if (inst == null)
{
int seed;
lock (_global) seed = _global.Next();
_localInstance = inst = new Random(seed);
}
return _localInstance;
}
}
}
【问题讨论】:
标签: c# thread-safety random