C#的Random.Next()
方法线程安全吗?
发布于 2010-06-16 06:19:19
在Next
方法中没有做任何特殊的事情来实现线程安全。然而,它是一个实例方法。如果您不跨不同的线程共享Random
的实例,则不必担心实例中的状态损坏。在没有持有某种排它锁的情况下,不要跨不同的线程使用Random
的单个实例。
Jon Skeet在这个主题上有几个很好的帖子:
正如一些评论员所指出的,在使用不同的Random
实例时存在另一个潜在的问题,这些实例是线程独占的,但是被相同地播种,因此导致相同的伪随机数序列,因为它们可能是在同一时间创建的,或者彼此在时间上非常接近。缓解该问题的一种方法是使用主Random
实例(由单个线程锁定)来生成一些随机种子,并初始化新的Random
实例,供每个其他线程使用。
发布于 2012-06-20 04:59:34
不,从多个线程使用相同的实例可能会导致它中断并返回全0。然而,创建线程安全版本(不需要在每次调用Next()
时都使用讨厌的锁)很简单。改编自this article中的想法
public class ThreadSafeRandom
{
private static readonly Random _global = new Random();
[ThreadStatic] private static Random _local;
public int Next()
{
if (_local == null)
{
int seed;
lock (_global)
{
seed = _global.Next();
}
_local = new Random(seed);
}
return _local.Next();
}
}
这个想法是为每个线程保留一个单独的static Random
变量。然而,由于Random
的另一个问题-如果几乎同时创建多个实例(大约在15ms内),它们都将返回相同的值,以明显的方式失败!为了解决这个问题,我们创建了一个全局静态的Random
实例来生成每个线程使用的种子。
顺便说一句,上面的文章使用Random
演示了这两个问题。
发布于 2010-06-16 06:28:52
不,它不是线程安全的。如果你需要从不同的线程使用同一个实例,你必须同步使用。
不过,我真的看不出你有什么理由需要它。对于每个线程来说,拥有自己的Random类实例会更有效率。
https://stackoverflow.com/questions/3049467
复制相似问题