首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C#随机数生成器线程安全吗?

C#随机数生成器线程安全吗?
EN

Stack Overflow用户
提问于 2010-06-16 06:17:43
回答 11查看 52.6K关注 0票数 90

C#的Random.Next()方法线程安全吗?

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2010-06-16 06:19:19

Next方法中没有做任何特殊的事情来实现线程安全。然而,它是一个实例方法。如果您不跨不同的线程共享Random的实例,则不必担心实例中的状态损坏。在没有持有某种排它锁的情况下,不要跨不同的线程使用Random的单个实例。

Jon Skeet在这个主题上有几个很好的帖子:

StaticRandom

Revisiting randomness

正如一些评论员所指出的,在使用不同的Random实例时存在另一个潜在的问题,这些实例是线程独占的,但是被相同地播种,因此导致相同的伪随机数序列,因为它们可能是在同一时间创建的,或者彼此在时间上非常接近。缓解该问题的一种方法是使用主Random实例(由单个线程锁定)来生成一些随机种子,并初始化新的Random实例,供每个其他线程使用。

票数 35
EN

Stack Overflow用户

发布于 2012-06-20 04:59:34

不,从多个线程使用相同的实例可能会导致它中断并返回全0。然而,创建线程安全版本(不需要在每次调用Next()时都使用讨厌的锁)很简单。改编自this article中的想法

代码语言:javascript
复制
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演示了这两个问题。

票数 95
EN

Stack Overflow用户

发布于 2010-06-16 06:28:52

不,它不是线程安全的。如果你需要从不同的线程使用同一个实例,你必须同步使用。

不过,我真的看不出你有什么理由需要它。对于每个线程来说,拥有自己的Random类实例会更有效率。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3049467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档