Here is a question my study group is arguing about:
(g) Consider the following C# code:
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");
}
}
}
}
This is a multi-threaded program, so different executions may produce different results. Place a check-mark next to the complete output that the program might produce. (The last choice stands for no output.)
Output Answer
Output——-Possible?
GH
HG
G
H
(nothing)
What we think:
GH would be the output if t1 locked b before t2 locked b.
(nothing) would be the output if t1 locked a and then t2 locked b, because it would cause a deadlock
G would be the output if t1 locked b, and then while t1 still held the lock on b, t2 started, because the t2.wait would be waiting on t1 to finish.
Can’t think of how you could possibly get H or HG. However, one of us ran the code 200,000 times, and he got HG sometimes… I don’t understand
I just don’t feel certain about these answers though. What do you all think? Any help is greatly appreciated!
If you are ever getting a single letter, that means one thread managed to obtain both locks. Which also means it will be able to release both locks, and the other thread will complete successfully – and print the other letter. With this reasoning, both
GHandHGare possible outputs. Also, it is possible to hit the deadlock case, where thread 1 holds one lock, and thread 2 holds the other.