Ожидание стыковки

Wait и Pulse можно использовать так же, как для стыковки двух потоков используется WaitHandle.SignalAndWait. В следующем примере, можно сказать, имитируются два ManualResetEvent (другими словами, мы определяем два булевых флажка!), а затем выполняется взаимная сигнализация-и-ожидание установкой одного флага при ожидании другого. В данном случае нет необходимости в истинной атомарности сигнализации-и-ожидания, так что нет нужды и в двухфазном commit. Пока мы устанавливаем наш флаг и вызываем Wait в пределах одного lock -а, стыковка будет работать:

class Rendezvous { static object locker = new object(); static bool signal1, signal2; static void Main() { // Заставим каждый поток бездействовать в течение // случайного промежутка времени Random r = new Random(); new Thread(Mate).Start(r.Next(10000)); Thread.Sleep(r.Next(10000)); lock (locker) { signal1 = true; Monitor.Pulse(locker); while (!signal2) Monitor.Wait(locker); } Console.Write("Одновременно! "); } // Этот метод вызывается в потоке static void Mate(object delay) { Thread.Sleep((int) delay); lock (locker) { signal2 = true; Monitor.Pulse(locker); while (!signal1) Monitor.Wait(locker); } Console.Write("Одновременно! "); } }

Консольный вывод:

Одновременно! Одновременно! (почти одновременно)

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: