C# 以线程安全的方式获取随机数

C# 以线程安全的方式获取随机数,c#,.net,multithreading,random,thread-safety,C#,.net,Multithreading,Random,Thread Safety,下面是一篇很好的文章,描述了随机数的线程安全性: 但我坚持使用“RandomGen2”的例子: } 为什么线程静态字段被复制到局部变量:Random inst=_local?为什么不直接使用 if(_local==null) .... return _local.Next()注意:写下这个答案后,我意识到创建多个随机实例的问题,尽管听起来它应该可以工作。我通常发现一个更好的选择是使用一个Random实例并锁定它。尽管这是一个潜在的瓶颈,但在大多数应用程序中,它不会导致问题 我怀疑这只是为了避免

下面是一篇很好的文章,描述了随机数的线程安全性:

但我坚持使用“RandomGen2”的例子:

}

为什么线程静态字段被复制到局部变量:Random inst=_local?为什么不直接使用

if(_local==null)
....

return _local.Next()

注意:写下这个答案后,我意识到创建多个
随机
实例的问题,尽管听起来它应该可以工作。我通常发现一个更好的选择是使用一个
Random
实例并锁定它。尽管这是一个潜在的瓶颈,但在大多数应用程序中,它不会导致问题


我怀疑这只是为了避免多次读取线程静态变量的成本。与读取局部变量相比,这样做效率相对较低

你的建议行得通,但效率会稍低,仅此而已。在其他情况下,可能会在抓取之间更改值,但在本例中这当然不是问题,因为它是一个线程局部变量

对于.NET 4及更高版本,使用
ThreadLocal
会更简单:

公共静态类RandomGen2
{ 
private static Random_global=new Random();
私有静态ThreadLocal\u local=新ThreadLocal(()=>
{
int种子;
lock(_global)seed=_global.Next();
返回新的随机(种子);
});
公共静态int Next()
{ 
返回_local.Value.Next();
} 
}

重要注意事项,当您像这样链接随机数生成器时,您可以得到。哪一个性能最好(如果有差异)?ThreadLocal还是[ThreadStatic]?@krimog:我认为
ThreadLocal
性能更好,但您必须进行测试才能确定。它也可能取决于架构。所以,我做了测试(i5在32位操作系统上,使用fwk4.0)。这两种方法的性能似乎非常相似,但[ThreadStatic]的优势很小(在平均值上,<5%)。官方文档中有一个很好的例子和解释:
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(); 
   } 
public static class RandomGen2 
{ 
    private static Random _global = new Random(); 
    private static ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
    {
        int seed;
        lock (_global) seed = _global.Next();
        return new Random(seed);
    });


    public static int Next() 
    { 
        return _local.Value.Next();
    } 
}