以线程安全的方式获取随机数 [英] Getting random numbers in a thread-safe way
问题描述
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屋!