我有以下功能:
//Function to get random number
public static int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
Run Code Online (Sandbox Code Playgroud)
我怎么称呼它:
byte[] mac = new byte[6];
for (int x = 0; x < 6; ++x)
mac[x] = (byte)(Misc.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);
Run Code Online (Sandbox Code Playgroud)
如果我在运行时使用调试器执行该循环,则会得到不同的值(这就是我想要的).但是,如果我在该代码下面放置一个断点两行,则"mac"数组的所有成员都具有相同的值.
为什么会这样?
为了给出一些上下文,我一直在用Java编写一个基本的Perlin噪声实现,当实现种子时,我遇到了一个我无法解释的错误.
为了每次为相同的种子生成相同的随机权重向量,无论查询哪个坐标的噪声级别以及以什么顺序查询,我都newSeed基于原始种子和坐标的组合生成了新的种子()通过运行以下权重向量,并将其用作权重向量随机化的种子:
rnd.setSeed(newSeed);
weight = new NVector(2);
weight.setElement(0, rnd.nextDouble() * 2 - 1);
weight.setElement(1, rnd.nextDouble() * 2 - 1);
weight.normalize()
Run Code Online (Sandbox Code Playgroud)
NVector矢量数学的自制类在哪里?
但是,运行时,程序产生了非常糟糕的噪音:

经过一些挖掘,我发现每个向量的第一个元素非常相似(因此nextDouble()每次setSeed()调用后的第一个调用)导致向量网格中每个向量的第一个元素相似.
这可以通过运行来证明:
long seed = Long.valueOf(args[0]);
int loops = Integer.valueOf(args[1]);
double avgFirst = 0.0, avgSecond = 0.0, avgThird = 0.0;
double lastfirst = 0.0, lastSecond = 0.0, lastThird = 0.0;
for(int i = 0; i<loops; i++)
{
ran.setSeed(seed + i);
double first = ran.nextDouble();
double second = ran.nextDouble();
double third = …Run Code Online (Sandbox Code Playgroud) 这是一篇很好的文章,描述了随机数的线程安全性:以线程安全的方式获取随机数
但我坚持使用"RandomGen2"示例:
public static class RandomGen2
{
private static Random _global = new Random();
[ThreadStatic]
private static Random _local;
public static int Next()
{
Random inst = _local;
if (inst == null)
{
int seed;
lock (_global) seed = _global.Next();
_local = inst = new Random(seed);
}
return inst.Next();
}
Run Code Online (Sandbox Code Playgroud)
}
为什么线程静态字段被复制到局部变量:Random inst = _local; ?为什么不简单地使用
if (_local == null)
....
return _local.Next()
我最近在另一篇文章的评论中讨论了相同类型的多个随机数生成器的初始化,在讨论中我们询问了以下问题:
1)使用不同的种子创建相同随机数生成器的多个实例并在程序的不同部分使用这些随机数生成器是一个好主意吗?
2)特别是,使用.Net Random类创建随机数生成器的技术,如下所示,并在不同的程序上下文中使用每个RNG会导致问题:
int size = 64; // The number of RNGs to use
int seed; // Get seed using some normal technique
Random[] r = new Random[size];
for (int i = 0; i < size; i++)
{
r[i] = new Random(seed + i);
}
Run Code Online (Sandbox Code Playgroud)
3)如果需要多个随机数流,你会建议什么?
4)当需要线程安全时,您如何建议生成随机数?