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

C# Random.Next()有时在不同的线程中返回相同的数字,c#,multithreading,random,C#,Multithreading,Random,我有以下课程 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();

我有以下课程

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);
      ...
   }
}
类程序
{
静态随机_Random=新随机();
静态void Main(字符串[]参数)
{
...
对于(int i=0;i

代码创建指定数量的线程,启动每个线程,并为每个线程分配一个随机的
设备id
。出于某种原因,创建的前两个线程通常具有相同的
设备id
。我不明白为什么会发生这种情况。

随机是一个伪随机数生成器,没有什么可以阻止它为多个调用返回相同的结果。毕竟这是有可能发生的。更不用说,根据该报告:

任何实例成员都不能保证线程安全


因此,您根本不应该从多个线程调用该方法。

Random不是线程安全的-您不应该从多个线程使用同一实例。它可能比仅仅返回相同的数据要糟糕得多——通过从多个线程使用它,您可以让它“卡住”在一个状态中,它将始终返回0,IIRC

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


我有一个示例代码,它详细介绍了这一点,并提供了一个实现,该实现使用递增种子惰性地实例化每个线程的一个
Random

您的示例代码只显示了每个线程的一个
\u Random
用法。假设是这种情况,您还可以在主
for
循环中生成随机数,并将随机数作为参数传递给每个线程

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

这在统计学上是正确的,就像你掷2个骰子,他们有时会给你相同的数字,再加上Random不是线程安全的->@Mitch:没有一个相关的问题处理相同的情况。这里只涉及线程安全,因为只有一个Random实例。@Jon:是的,没错。听上去,如果两个线程使用相同的设备id,这会给你带来问题。如果是这样的话,那么你无论如何也不应该使用随机分配-你应该做一些确保没有碰撞的事情。@dvvh:是的,但是内部空间足够大,所以碰撞不会每隔一次发生。问题已经解决了,tho。我也这么怀疑,但即使在检查MSDN后也不确定。我也会看看你的文章。谢谢。另请看Jon Skeet的。
 static void Send(int device_id)
 {
    ...
    //int device_id = _Random.Next(999999);
    ...
 }