This question already has answers here:
Random String Generator Returning Same String [duplicate]
(30个答案)
Why do I keep getting two of same random values in this code? [duplicate]
(5个答案)
6年前关闭。
在class1和class2的构造函数中,我有:
在两个类中,随机值“超时”始终相同。我不明白为什么。
如果我在创建任务之间添加了暂停,则不一样。
编辑:
我不明白这与“Random String Generator Returning Same String”有何关系。
他们正在方法中创建随机实例。我在完全不同的任务中称呼它,因此它们应该彼此独立。
重要的是要注意,每次对
现在,您可以创建任务并运行它们,并获得适当的随机性:
请注意,当忽略
(30个答案)
Why do I keep getting two of same random values in this code? [duplicate]
(5个答案)
6年前关闭。
Task.Factory.StartNew(() =>
{
new Class1();
})
Task.Factory.StartNew(() =>
{
new Class2();
})
在class1和class2的构造函数中,我有:
var timeout = new Random().Next(0, 5000);
Debug.Print(timeout.ToString());
在两个类中,随机值“超时”始终相同。我不明白为什么。
如果我在创建任务之间添加了暂停,则不一样。
编辑:
我不明白这与“Random String Generator Returning Same String”有何关系。
他们正在方法中创建随机实例。我在完全不同的任务中称呼它,因此它们应该彼此独立。
最佳答案
尽管根本原因是相同的,但它并不直接相关。一个更好的副本是这个问题:Why do I keep getting two of same random values in this code?
它包含new Random
的功能an explanation –由documentation提供:
换句话说:如果快速连续创建Random
对象,它们将产生相同的随机数序列。
这些对象是否在不同的线程(或Task
)中创建是无关紧要的-它们仅取决于创建它们时的系统时间,而无其他依赖。正如您所说,它们实际上彼此独立。但是它们都依赖于相同的种子值,即创建时的系统时间。
解决此的正确方法通常是仅包含Random
类的一个实例。 –实际上,这样的代码是:new Random().Next(…)
是代码气味,因为它滥用了Random
类:您不应该为每个调用都生成一个新实例;相反,您应该重用同一实例来生成一个随机数序列。
不幸的是,您不能简单地在不同的并发任务中使用相同的Random
实例,因为relevant method并非线程安全的-也就是说,同时从多个线程中调用它可能导致竞争。有几种解决方法,但是最简单的方法是使用显式锁:
public Class(Random rng) {
lock (rng) {
var timeout = rng.Next(5000);
Debug.Print(timeout.ToString());
}
}
重要的是要注意,每次对
rng
的访问都必须被锁定,否则就没有意义了。现在,您可以创建任务并运行它们,并获得适当的随机性:
var rng = new Random();
var tasks = new [] {
Task.Run(() => { new Class(rng); }),
Task.Run(() => { new Class(rng); })
};
Task.WaitAll(tasks);
请注意,当忽略
lock(…)
块时,您似乎正在获得正确的结果。这是使用并发性和随机性的危险:很难验证您的结果是否正确或在整个过程中是否被破坏。因此,请谨慎行事。关于c# - 为什么两个彼此创建的任务会生成相同的随机值? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24600937/
10-16 17:21