Eric Lippert和Neal Gafter C#拼图
这个难题是在2010年NDC展会上展示的。从那里有video的链接,但是它们都被破坏了。 我不明白这个scheme的行为。 为什么它挂起?
class Woot { private static float PI; private static bool initialized = doInitialize(); private static bool doInitialize() { if (!initialized) { var thread = new Thread(() => { PI = 3.14f; }); thread.Start(); thread.Join(); // here } return true; } public static void Main(string[] args) { Console.WriteLine(PI); } }
这个程序的输出是什么? 是吗:
- 3.14
- 0
- 引发exception
- 以上都不是
我认为这个问题是由静电场发生器引起的。 我发现只有在doInitialize
完成时才启动新线程(尽pipethread.Start()
) – 所以我想CLR会阻止其他线程来避免并发访问/双字段初始化 。
综上所述 :新创build的线程不是由CLR启动的,以避免并发访问,而主要的线程线程等待子线程完成意味着死锁 。
编辑
@塞巴斯蒂安(在评论中)提出了可能certificate我的理论的链接: http : //blogs.msdn.com/b/pfxteam/archive/2011/05/03/10159682.aspx
doInitialize
在构造静态types时执行,然后暂停,直到设置PI
的线程终止。
试图设置PI
的线程在初始化之前不能运行,只有在初始化(静态构造函数和静态初始化函数)完成之后才会发生,而这些还没有像上面那样发生。
所以程序死锁。
另请参阅Eric Lippert的答案 。
线程永远不会完成,所以thread.Join()将永远不会返回。 doInitialize()是从静态构造函数中执行的。 在静态构造函数中,我们试图设置静态属性,但除非静态构造函数完成,否则我们无法访问静态属性。 种族