C# NET中的随机和线程问题
我在.NET中的类遇到了问题,我正在实现一个线程集合,除了一个较小的细节外,它工作得很好。该集合是一个集合,熟悉它的人都知道,对于插入的每个节点,我需要生成一个新高度,即C# NET中的随机和线程问题,c#,.net,multithreading,data-structures,collections,C#,.net,Multithreading,Data Structures,Collections,我在.NET中的类遇到了问题,我正在实现一个线程集合,除了一个较小的细节外,它工作得很好。该集合是一个集合,熟悉它的人都知道,对于插入的每个节点,我需要生成一个新高度,即尝试锁定随机对象 int RandomLevel() { int height = 1; lock(rnd) { while(rnd.NextDouble >= 0.5 && height < MaxHeight) height++; } r
尝试锁定随机对象
int RandomLevel()
{
int height = 1;
lock(rnd)
{
while(rnd.NextDouble >= 0.5 && height < MaxHeight) height++;
}
return height;
}
int RandomLevel()
{
整数高度=1;
锁(rnd)
{
而(rnd.NextDouble>=0.5&&height
当多个线程同时访问Random
对象时,可能存在冲突问题,并且种子可能已损坏。我无法对具体发生的情况提供任何见解,但根据实例,Random
类型的成员不能保证线程安全,因此在任何情况下都需要使用锁。看起来您的循环运行时间不到调用时间的一半-这就是您要寻找的吗(当0和1之间的随机数>0.5时?这可以解释为什么得到“1”的频率比预期的要高-至少有一半的时间,它甚至没有运行增加高度的循环-它只是将高度设置为1,不改变它,然后返回“1”.我不熟悉跳过列表,所以这可能是故意的,但我想我会问一下
我不太熟悉使用随机数,但你是否可能有一个播种问题?如果你不随机化随机对象,当你实例化它时,它可能返回一个可预测的数字流,而不是真正随机的。也许不会引起你在这里看到的行为,但是要考虑MOV。我不会锁定整个while循环。只需锁定rnd.NextDouble()调用即可
int RandomLevel()
{
整数高度=1;
双纽兰;
lock(rnd){newRand=rnd.NextDouble();}
而(newRand>=0.5&&height
虽然如果性能是一个考虑因素,我当然会比较这两种解决方案,因为单线程和多线程性能可能会有所不同。在哪里声明了rnd
呢?是randomlevel()从一个单独的线程调用?为了清晰起见,添加了声明,声明一次,然后从几个不同的线程调用。您应该这样锁定它:double d;lock(rnd)d=rnd.NextDouble();这是更好的性能检查整个while循环似乎是一个有点糟糕的主意。Benny:我不怀疑你,但想解释一下原因吗?在我看来,这会带来更差的性能,因为我需要多次执行锁定操作。一个线程保持锁定的时间越长,其他线程阻塞的时间就越长。你可以有一个单独的Rand实例每个线程的om对象。例如,通过使用[ThreadStatic]属性。在这种情况下不需要锁定。
int RandomLevel()
{
int height = 1;
lock(rnd)
{
while(rnd.NextDouble >= 0.5 && height < MaxHeight) height++;
}
return height;
}
int RandomLevel()
{
int height = 1;
double newRand;
lock(rnd) { newRand = rnd.NextDouble(); }
while(newRand >= 0.5 && height < MaxHeight)
{
height++;
lock(rnd) { newRand = rnd.NextDouble(); }
}
return height;
}