以下是我的研究小组提出的一个问题:
(g)考虑以下C#代码:
public class Demo {
private static readonly object a = new object();
private static readonly object b = new object();
public static void Main (string[] args) {
Demo d = new Demo();
Task t1 = Task.Factory.StartNew(d.g);
Task t2 = Task.Factory.StartNew(d.h);
t2.Wait();
t1.Wait();
}
private void g() {
lock (a) {
lock (b) {
Console.Write("G");
}
}
}
private void h() {
lock (b) {
lock (a) {
Console.Write("H");
}
}
}
}
这是一个多线程程序,因此不同的执行可能会产生不同的结果。在程序可能生成的完整输出旁边放置一个复选标记。 (最后一个选择代表无输出。) 输出答案
输出-------可能?
GH
HG
G
H
(nothing)
我们的想法:
如果在t2锁定b之前t1锁定b,则GH将是输出。
如果t1锁定a然后t2锁定b,(无)将是输出,因为它会导致死锁
如果t1锁定b,则G将是输出,然后当t1仍然保持b上的锁定时,t2开始,因为t2.wait将等待t1完成。
想不出你怎么可能得到H或HG。但是,我们中的一个人运行了200,000次代码,有时他得到了HG ......我不明白
我只是不确定这些答案。你们都觉得怎么样?非常感谢任何帮助!
答案 0 :(得分:0)
绝对不能保证在g()
之前启动h()
。据我所知,StartNew()
实际上并没有启动任务,而是将其排队等待下一个可用的线程。
答案 1 :(得分:0)
我认为只获得G或只有H的唯一方法是同时完成两个功能,但程序在控制台刷新第二个字母之前结束。
答案 2 :(得分:0)
如果您收到一封信,那意味着一个线程设法获得两个锁。这也意味着它将能够释放两个锁,另一个线程将成功完成 - 并打印另一个字母。有了这个推理,GH
和HG
都是可能的输出。此外,有可能遇到死锁情况,其中线程1持有一个锁,而线程2持有另一个。
答案 3 :(得分:0)
HG可能发生,因为无法保证新线程何时开始执行。创建Task t2
后,操作系统可以先运行它,然后返回并运行t1
。