Tar*_*rec 37 c# random thread-safety threadstatic
我自己写了一个多线程随机生成器
public static class MyRandGen
{
private static Random GlobalRandom = new Random();
[ThreadStatic]
private static Random ThreadRandom = new Random(SeedInitializer());
private static int SeedInitializer()
{
lock (GlobalRandom) return GlobalRandom.Next();
}
public static int Next()
{
return ThreadRandom.Next();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,它在抛出Next()时抛出了NullReferenceException,我不明白.这种初始化ThreadStatic字段是否被禁止?
我知道我可以检查每次都是否已初始化该字段,但这不是我正在寻找的解决方案.
hat*_*ica 61
初始化ThreadStatic字段有点棘手.特别是有一点需要注意:
不要为标记有ThreadStaticAttribute的字段指定初始值,因为这样的初始化只在类构造函数执行时发生一次,因此只影响一个线程.
在MSDN文档中.这意味着初始化类时运行的线程获取您在字段声明中定义的初始值,但所有其他线程的值都为null.我认为这就是为什么您的代码表现出您的问题中描述的不良行为的原因.
更全面的解释是在这篇博客中.
(来自博客的片段)
[ThreadStatic]
private static string Foo = "the foo string";
Run Code Online (Sandbox Code Playgroud)
ThreadStatic在静态构造函数中初始化 - 它只执行一次.因此,当静态构造函数执行时,只有第一个线程被赋予"foo字符串".在所有后续线程中访问时,Foo保留在未初始化的空值.
解决此问题的最佳方法是使用属性访问Foo prop.
[ThreadStatic]
private static string _foo;
public static string Foo {
get {
if (_foo == null) {
_foo = "the foo string";
}
return _foo;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,静态属性中不需要锁定,因为每个线程都只_foo
对该线程执行操作.其他线程无法争用.这个问题包含在这个问题中:ThreadStatic和Synchronization
归档时间: |
|
查看次数: |
7989 次 |
最近记录: |