【问题标题】:Getting random numbers in a thread-safe way以线程安全的方式获取随机数
【发布时间】:2014-10-16 08:52:45
【问题描述】:

这是一篇很好的文章,描述了随机数的线程安全:Getting random numbers in a thread-safe way

但我坚持使用“RandomGen2”示例:

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(); 
   } 

}

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

if (_local == null) .... return _local.Next()

【问题讨论】:

标签: c# .net multithreading random thread-safety


【解决方案1】:

注意:自从写下这个答案后,我已经意识到创建多个 Random 实例的问题,即使它听起来应该可以工作。我通常发现更好的选择是拥有一个 Random 实例并锁定它。虽然这是一个潜在的瓶颈,但在大多数应用程序中它不会造成问题。


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

您的建议会奏效,但效率会稍低,仅此而已。在其他情况下,值可能会在两次提取之间发生变化 - 但在这种情况下这当然不是问题,因为它是一个线程局部变量。

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

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();
    } 
}

【讨论】:

  • 哪一个性能最好(如果有区别的话)? ThreadLocal 或 [ThreadStatic] ?
  • @krimog:我认为 ThreadLocal&lt;T&gt; 表现更好,但您必须进行测试才能确定。它也可能依赖于架构。
  • 所以,我进行了测试(i5 在 32 位操作系统上使用 fwk 4.0)。这两种方法的性能似乎非常相似,但 [ThreadStatic] 的优势很小(平均
  • 官方文档中有很好的例子和解释:The System.Random class and thread safety
猜你喜欢
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多