3

我已经搜索过这个问题,但我找到的解决方案都没有帮助。也许有人可以帮助我。

我有以下循环:

private static readonly Random RANDOM = new Random();
...
int[] array; // is initialized, when used. ;)
if (array.Sum() != 0)
{
    int j = 0;
    do {
        j = RANDOM.Next(8);
    } while (array[j] == 0);
}

这整个循环在另一个循环中,而另一个循环又在一个循环中Parallel.Foreach。看来,j总是这样0。大多数时候它并不明显,但如果array[0] == 0,那么它不会脱离循环。我怀疑do-while-loop 可能太快了。但也在几秒钟后(~30)它不会离开循环。所以Random似乎没有返回新的或不同的值(即使在同一个线程中)。

我也试过这个解决方案,但没有效果。

4

3 回答 3

3

试试这个,因为 Random 不是线程安全的:

private static Random RANDOM = new Random();
private static object _randomLock = new object();

...

int[] array; // is initialized, when used. ;)
if (array.Sum() != 0)
{
    int j = 0;
    do {
        lock(_randomLock)
        {
            j = RANDOM.Next(8);
        }
    } while (array[j] == 0);
}
于 2013-05-31T20:28:58.180 回答
2

感谢您的快速回答。 马修的回答已经给了我我需要的东西。
我用了

public static class RandomGen2 
{ 
    private static Random _global = new Random(); 
    [ThreadStatic] 
    private static Random _local; 

    public static int Next() 
    { 
        Random inst = _local; 
        if (inst == null) 
        { 
            int seed; 
            lock (_global) seed = _global.Next(); 
            _local = inst = new Random(seed); 
        } 
        return inst.Next(); 
    } 
}

为我的解决方案。它工作得很好而且很快。

于 2013-05-31T20:44:08.917 回答
1

Random 不是线程安全的,并且对于并行操作来说不够随机。考虑使用线程安全的 RNG,例如RNGCryptoServiceProvider,但要知道它会比 Random 慢一点,因为生成数字的算法要复杂得多。

于 2013-05-31T20:28:31.700 回答