以线程安全的方式获取随机数 [英] Getting random numbers in a thread-safe way

查看:387
本文介绍了以线程安全的方式获取随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一篇不错的文章,描述了随机数的线程安全性:

Here is a nice article describing thread safety of random numbers:Getting random numbers in a thread-safe way

但是我一直停留在"RandomGen2"示例中:

But I'm stuck with the "RandomGen2" example:

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; ?为什么不简单地使用

Why is the thread static field copied to local variable: Random inst = _local; ? Why not to simply use

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

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

推荐答案

注意:自从编写此答案以来,尽管听起来好像应该可以工作,但我已经意识到创建多个Random实例的问题.我通常发现,更好的选择是只有一个Random实例,然后锁定它.尽管这是一个潜在的瓶颈,但在大多数应用程序中,它不会引起问题.

Note: since writing this answer, I've become aware of issues creating multiple Random instances, even though it sounds like it should work. I've generally found that a better alternative is to have a single Random instance and just lock on that. Although that is a single potential bottleneck, in most applications it won't cause problems.

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

I suspect it's just to avoid the cost of reading the thread-static variable multiple times. It's relatively inefficient to do so, compared with reading a local variable.

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

Your suggestion would work, but it would be slightly less efficient, that's all. In other cases, there would be the possibility of the value changing between fetches - but of course that's not a problem in this case, as it's a thread-local variable.

在.NET 4和更高版本中,使用ThreadLocal<T>会更简单:

With .NET 4 and higher, this would be simpler using 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();
    } 
}

这篇关于以线程安全的方式获取随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆