多线程锁定,有趣的时间(练习期中考试)



我的学习小组正在讨论一个问题:

(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)

我们的想法:

如果t1在t2锁定b之前锁定b, GH将是输出。

如果t1锁定a,然后t2锁定b,则输出

(无),因为这会导致死锁

G将是t1锁定b时的输出,然后当t1仍然锁定b时,t2开始,因为t2。Wait表示等待t1完成。

我想不出你怎么可能得到H或HG.然而,我们中的一个人运行了20万次代码,他有时会得到HG…我不明白

我只是不确定这些答案。你们怎么想?任何帮助都非常感谢!

如果您得到一个字母,那就意味着一个线程设法获得了两个锁。这也意味着它将能够释放两个锁,而另一个线程将成功完成——并打印另一个字母。由此推理,GHHG都是可能的输出。另外,也有可能发生死锁,即线程1持有一个锁,线程2持有另一个锁。

不能保证g()会在h()之前启动。据我所知,StartNew()实际上并不启动任务,而是为下一个可用的线程排队。

我认为只得到G或H的唯一方法是让两个函数都完成,但程序在控制台刷新第二个字母之前结束。

可能发生HG,因为无法保证新线程何时开始执行。创建Task t2后,操作系统可以先运行它,然后返回并运行t1

最新更新