Jea*_*rdi 5 c# random thread-safety
我正在使用.NET创建一个人工生命程序,我正在使用C#在Singleton中定义的伪随机类.我的想法是,如果我在整个应用程序中使用相同的随机数生成器,我只能保存种子,然后从种子重新加载以重新计算某个有趣的运行.
public sealed class RandomNumberGenerator : Random
{
private static readonly RandomNumberGenerator instance = new RandomNumberGenerator();
RandomNumberGenerator()
{
}
public static RandomNumberGenerator Instance
{
get
{
return instance;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还想要一个可以给我两个不同随机数的方法.
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);
}
Run Code Online (Sandbox Code Playgroud)
问题是有时候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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 3
如果您仅对多个线程使用一个 RNG,即使您保存了种子,您也将无法在下次启动应用程序时生成相同的数字,因为您无法确定从不同的地方对 RNG 的调用是否正确。线程将按相同的顺序排列。
如果您有固定/已知数量的线程,请为每个线程创建一个 RNG 并保存每个种子。
如果您 100% 确定每个线程都会以与上次使用相同种子时完全相同的顺序调用 RNG,请忘记我刚才所说的内容。
| 归档时间: |
|
| 查看次数: |
2066 次 |
| 最近记录: |