Добавить в цитаты Настройки чтения

Страница 407 из 502

Ниже приведены общие формы методов Pulse() и PulseAll():

<b>public static void Pulse(object obj)</b>

<b>public static void PulseAll(object obj)</b>

где obj обозначает освобождаемый объект.

Если методы Wait(),Pulse() и PulseAll() вызываются из кода, находящегося за пределами синхронизированного кода, например из блока lock, то генерируется исключение SynchronizationLockException.

Для того чтобы стало понятнее назначение методов Wait() и Pulse(), рассмотрим пример программы, имитирующей тиканье часов и отображающей этот процесс на экране словами "тик" и "так". Для этой цели в программе создается класс TickTock, содержащий два следующих метода: Tick() и Тоск(). Метод Tick() выводит на экран слово "тик", а метод Тоск() — слово "так". Для запуска часов далее в программе создаются два потока: один из них вызывает метод Tick(), а другой — метод Тоск(). Преследуемая в данном случае цель состоит в том, чтобы оба потока выполнялись, поочередно выводя на экран слова "тик" и "так", из которых образуется повторяющийся ряд "тик-так", имитирующий ход часов.

<b>//Использовать методы Wait() и Pulse() для иммитации</b>

<b>//тиканья часов</b>

<b>using System;</b>

<b>using System.Threading;</b>

<b>class TickTock {</b>

<b>  object lockOn = new object();</b>

<b>  public void Tick(bool ru

<b>    lock(lockOn) {</b>

<b>      if(!ru

<b>        Monitor.Pulse(lockOn); // уведомить любые ожидающие потоки</b>

<b>        return;</b>

<b>      }</b>

<b>      Console.Write(&quot;тик &quot;);</b>

<b>      Monitor.Pulse(lockOn); // разрешить выполнение метода Tock()</b>

<b>      Monitor.Wait(lockOn);    // ожидать завершения метода Tock()</b>

<b>    }</b>

<b>  }</b>

<b>  public void Tock(bool ru

<b>    lock(lockOn) {</b>

<b>      if(!ru

<b>        Monitor.Pulse(lockOn); // уведомить любые ожидающие потоки </b>

<b>        return;</b>

<b>      }</b>

<b>      Console.WriteLine(&quot;так&quot;);</b>

<b>      Monitor.Pulse(lockOn); // разрешить выполнение метода Tick()</b>

<b>      Monitor.Wait(lockOn);    // ожидать завершения метода Tick()</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

<b>class MyThread {</b>

<b>  public Thread Thrd;</b>

<b>  TickTock ttOb;</b>

<b>  // Сконструировать новый поток.</b>

<b>  public MyThread(string name, TickTock tt) {</b>

<b>    Thrd = new Thread(this.Run);</b>

<b>    ttOb = tt;</b>

<b>    Thrd.Name = name;</b>

<b>    Thrd.Start();</b>

<b>  }</b>

<b>  // Начать выполнение нового потока,</b>

<b>  void Run() {</b>

<b>    if(Thrd.Name == &quot;Tick&quot;) {</b>

<b>      for(int i=0; i&lt;5; i++)</b>

<b>        ttOb.Tick(true);</b>

<b>      ttOb.Tick(false) ;</b>

<b>    }</b>

<b>    else {</b>

<b>      for(int i=0; i&lt;5; i++)</b>

<b>        ttOb.Tock(true);</b>

<b>      ttOb.Tock(false);</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

<b>class TickingClock {</b>

<b>  static void Main() {</b>

<b>    TickTock tt = new TickTock();</b>

<b>    MyThread mt1 = new MyThread(&quot;Tick&quot;, tt);</b>

<b>    MyThread mt2 = new MyThread(&quot;Tock&quot;, tt);</b>