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

时间:2011-10-23 20:31:08

标签: multithreading locking thread-safety deadlock

以下是我的研究小组提出的一个问题:

(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 ......我不明白

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

4 个答案:

答案 0 :(得分:0)

绝对不能保证在g()之前启动h()。据我所知,StartNew()实际上并没有启动任务,而是将其排队等待下一个可用的线程。

答案 1 :(得分:0)

我认为只获得G或只有H的唯一方法是同时完成两个功能,但程序在控制台刷新第二个字母之前结束。

答案 2 :(得分:0)

如果您收到一封信,那意味着一个线程设法获得两个锁。这也意味着它将能够释放两个锁,另一个线程将成功完成 - 并打印另一个字母。有了这个推理,GHHG都是可能的输出。此外,有可能遇到死锁情况,其中线程1持有一个锁,而线程2持有另一个。

答案 3 :(得分:0)

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