我有以下课程
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
。我无法弄清楚为什么会这样。
答案 0 :(得分:26)
Random不是线程安全的 - 您不应该使用多个线程中的相同实例。它可能比返回相同的数据更糟糕 - 通过从多个线程使用它,你可以让它“卡住”在总是返回0,IIRC的状态。
显然,您不仅希望在大致相同的时间为每个线程创建一个新实例,因为它们最终将使用相同的种子...
我有一个article,它详细介绍了这一点,并提供了一个实现,它使用递增种子懒惰地为每个线程实例化一个Random
实例。
答案 1 :(得分:5)
Random是一个伪随机数生成器,并没有什么能阻止它为多次调用返回相同的结果。毕竟,这种情况发生的可能性很大。更不用说根据documentation:
不保证所有实例成员都是线程安全的。
所以你不应该从多个线程中调用Next方法。
答案 2 :(得分:2)
您的示例代码仅显示每个线程使用_Random
。假设是这种情况,您还可以在主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);
...
}