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