随机数生成器只生成一个随机数 [英] Random number generator only generating one random number

查看:65
本文介绍了随机数生成器只生成一个随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下功能:

//Function to get random number
public static int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
}

我怎么称呼它:

byte[] mac = new byte[6];
for (int x = 0; x < 6; ++x)
    mac[x] = (byte)(Misc.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);

如果我在运行时使用调试器执行该循环,我会得到不同的值(这是我想要的).但是,如果我在该代码下方两行放置一个断点,则 mac 数组的所有成员都具有相同的值.

If I step that loop with the debugger during runtime I get different values (which is what I want). However, if I put a breakpoint two lines below that code, all members of the mac array have equal value.

为什么会这样?

推荐答案

每次执行 new Random() 时,它都会使用时钟进行初始化.这意味着在紧密循环中,您多次获得相同的值.您应该保留一个 Random 实例并继续使用 下一步相同实例上.

Every time you do new Random() it is initialized using the clock. This means that in a tight loop you get the same value lots of times. You should keep a single Random instance and keep using Next on the same instance.

//Function to get a random number 
private static readonly Random random = new Random(); 
private static readonly object syncLock = new object(); 
public static int RandomNumber(int min, int max)
{
    lock(syncLock) { // synchronize
        return random.Next(min, max);
    }
}

<小时>

编辑(见评论):为什么我们需要一个 lock 在这里?

基本上,Next 将改变 Random 实例的内部状态.如果我们从多个线程同时执行此操作,您可能会争辩说我们只是让结果更加随机",但我们实际上正在做的可能是打破内部实现,我们也可以开始从不同的线程获取相同的数字,这可能是一个问题 - 也可能不是.不过,对内部发生的事情的保证是更大的问题;因为 Random保证线程安全.因此有两种有效的方法:

Basically, Next is going to change the internal state of the Random instance. If we do that at the same time from multiple threads, you could argue "we've just made the outcome even more random", but what we are actually doing is potentially breaking the internal implementation, and we could also start getting the same numbers from different threads, which might be a problem - and might not. The guarantee of what happens internally is the bigger issue, though; since Random does not make any guarantees of thread-safety. Thus there are two valid approaches:

  • 同步以便我们不会从不同的线程同时访问它
  • 每个线程使用不同的Random 实例

都可以;但是同时互斥来自多个调用方的单个实例只是自找麻烦.

Either can be fine; but mutexing a single instance from multiple callers at the same time is just asking for trouble.

lock 实现了这些方法中的第一个(也是更简单的);然而,另一种方法可能是:

The lock achieves the first (and simpler) of these approaches; however, another approach might be:

private static readonly ThreadLocal<Random> appRandom
     = new ThreadLocal<Random>(() => new Random());

这是每个线程的,所以你不需要同步.

this is then per-thread, so you don't need to synchronize.

这篇关于随机数生成器只生成一个随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆