2016-11-30 1 views
0

Ich fand dieses Beispiel in dem Buch. Und es steht geschrieben, dass dieser Code zu einem Deadlock führt. Aber ich verstehe es nicht und verstehe nicht warum es sein sollte? Ich bekomme immerTask Deadlock tritt nicht auf

„Locked B und A“

„Locked A und B“

static void Main() 
{ 
    object lockA = new object(); 
    object lockB = new object(); 
    var up = Task.Run(() => 
    { 
     lock (lockA) 
     { 
      Thread.Sleep(1000); 
      lock (lockB) 
      { 
       Console.WriteLine(“Locked A and B”); 
      } 
     } 
    }); 

    lock (lockB) 
    { 
     lock (lockA) 
     { 
      Console.WriteLine(“Locked B and A”); 
     } 
    } 

    up.Wait(); 
    Console.ReadLine(); 
} 
+0

Versuchen Sie, einen Schlaf im Hauptthread hinzuzufügen, nachdem Sie 'lockB' erworben haben. –

+0

10/10 Ergebnisse sind Deadlocks. Wieso ist es so? Ich dachte, es sollte eine gewisse Vielfalt sein. – Stalli

Antwort

2

Der Code ist nicht garantiert, in einer Sackgasse. Es gibt eine Race-Bedingung, ob es Deadlock wird oder nicht. Wenn die neu gestartete Task es schafft, die erste Sperre zu übernehmen, bevor der Hauptthread dieselbe Sperre einnimmt, dann blockiert der Code-Deadlock, wenn (wie es für Sie zweifellos der Fall ist) der erste Thread beide Sperren vor dem Worker-Thread erhält tut alles, dann gibt es keinen Stillstand.

+0

Vielen Dank für die Antwort. Und die Reihenfolge der Ausgabe ist auch nicht garantiert? Ich bekomme nur B-A, A-B und niemals A-B, B-A. Vielleicht muss ich mehr versuchen, andere Ergebnisse zu bekommen ... – Stalli

+0

@Stalli Während es technisch * möglich ist, dass die erstellte Aufgabe am Ende zu Ende geführt wird, ist dies praktisch unmöglich, so dass Sie es wahrscheinlich nie sehen werden diese Bestellung. – Servy

+0

Bedeutet es, dass der Haupt-Thread in der Regel von dem Moment an ausgeführt wird, in dem die Aufgabe ausgeführt wird? – Stalli