2016-11-30 4 views
0

Я нашел этот пример в книге. И написано, что этот код приводит к тупиковой ситуации. Но я не понимаю и не понимаю, почему это должно быть? Я всегда получаюЗаключительный тупик не возникает

«Locked B и A»

«Locked А и В»

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

Попробуйте добавить спать в основной поток, а также после того, как вы приобрели 'lockB'. –

+0

Результаты 10/10 являются взаимоблокировками. Почему это так? Должно быть, это должно быть какое-то разнообразие. – Stalli

ответ

2

Код не гарантированно тупиковой. Существует условие гонки относительно того, будет ли он заторможен. Если вновь запущенной задаче удается захватить первый замок до того, как основной поток продолжит захват той же самой блокировки, тогда кодовые блокировки, если (как это, без сомнения, происходит для вас), первый поток удается получить обе блокировки перед рабочим потоком ничего не делает, тогда нет тупика.

+0

Благодарим за ответ. И порядок выхода не гарантируется? Я просто получаю только B-A, A-B и никогда не A-B, B-A. Может быть, мне нужно попробовать больше, чтобы получить другой результат ... – Stalli

+0

@Stalli Хотя технически * возможно, что созданная задача в конечном итоге завершается до завершения, в любом практическом смысле это невозможно, так что вы вряд ли когда-нибудь увидите это заказ. – Servy

+0

Означает ли это, что основной поток обычно идет первым с момента запуска задачи? – Stalli

Смежные вопросы