Страницы

Поиск по вопросам

воскресенье, 7 апреля 2019 г.

Порядок запуска потоков

Всем привет. Подскажите пожалуйста почему идет запуск методов в потоках именно в таком порядке. Вот код:
using System; using System.Threading; class a { object o = new object(); public void Test() { lock (o) { Console.WriteLine("Start"); Monitor.Wait(o); Console.WriteLine("Stop"); } } public void UnLock() { lock(o) Monitor.Pulse(o); Console.WriteLine("Unlock"); for(int x = 0; x <10; x++) { Thread.Sleep(500); Console.WriteLine(x); } } } class b { static void Main() { a A = new a(); Thread t = new Thread(A.Test); t.Start(); Thread t1 = new Thread(A.UnLock); t1.Start(); } }
Я ожидаю что вначале запустится Test, потом написав слово Start он останавливается, потом запускается метод UnLock и при вызове в нем Pulse() метод Test не должен продолжать свое дело, так как Pulse() не снимает блокировку с объекта, однако как только вызывается Pulse(), то несмотря на заблокированный объект в методе Unlock, метод Test начинает продолжать свое дело. Почему так?? То есть я ожидаю вывод такой
Start Unlock 0....9 Stop
а получается
Start Unlock Stop 0....9
То есть видно, что метод Pulse говорит о освобождении объекта блокировки, и не смотря на то что он не освободился по факту, метод Test продолжает свою работу


Ответ

У вас в коде две проблемы. Первая - неправильный отступ. У вас сейчас на самом деле написано следующее:
public void UnLock() { lock(o) { Monitor.Pulse(o); }
Console.WriteLine("Unlock"); for(int x = 0; x <10; x++) { Thread.Sleep(500); Console.WriteLine(x); } }
как указал Pavel Mayorov, вы освобождаете лок сразу же после вызова Pulse
Вторая - само предположение, что второй поток будет запущен позже. Это многопоточность, и нет никаких гарантий что Test начнет выполнятся до UnLock. Даже починив lock, при определенном положении звезд, вы вполне можете получить вывод:
Unlock 0....9 Start
и зависание на Wait

Комментариев нет:

Отправить комментарий