Random.Next()有时会在不同的线程中返回相同的数字

我有以下课程

class Program { static Random _Random = new Random(); static void Main(string[] args) { ... for (int i = 0; i < no_threads; ++i) { var thread = new Thread(new ThreadStart(Send)); thread.Start(); } ... } static void Send() { ... int device_id = _Random.Next(999999); ... } } 

代码创建指定数量的线程,启动每个线程,并为每个线程分配一个随机的device_id 。 出于某种原因,创建的前两个线程通常具有相同的device_id 。 我无法弄清楚为什么会这样。

Random不是线程安全的 – 您不应该使用多个线程中的相同实例。 它可能比返回相同的数据更糟糕 – 通过从多个线程使用它,你可以让它“卡住”在一直返回0,IIRC的状态。

显然,你不只是想在大致相同的时间为每个线程创建一个新实例,因为它们最终将使用相同的种子……

我有一篇文章详细介绍了这一点,并提供了一个实现,它使用递增种子懒惰地实例化每个线程的一个Random实例。

Random是一个伪随机数生成器,没有什么能阻止它为多次调用返回相同的结果。 毕竟有可能发生这种情况。 更不用说根据文档 :

任何实例成员都不保证是线程安全的。

所以你不应该从多个线程中调用Next方法。

您的示例代码仅显示每个线程使用_Random 。 假设是这种情况,您还可以在main for循环中生成随机数,并将随机数作为参数传递给每个线程。

  for (int i = 0; i < no_threads; ++i) { var thread = new Thread(new ThreadStart(Send)); thread.Start(_Random.Next(999999)); } 

然后修改您的线程函数以接受参数:

  static void Send(int device_id) { ... //int device_id = _Random.Next(999999); ... }