Для того
чтобы стало понятнее назначение методовWait иPulse, рассмотрим пример программы, имитирующей тиканье часов и отображающей этот процесс на экране словами "тик" и "так". Для этой цели в программе создается классTickTock,содержащий два следующих метода:TickиТоск.МетодTick выводит на экран слово "тик", а методТоск () — слово "так". Для запуска часов далее в программе создаются два потока: один из них вызывает методTick, а другой — методТоск. Преследуемая в данном случае цель состоит в том, чтобы оба потока выполнялись, поочередно выводя на экран слова "тик" и "так", из которых образуется повторяющийся ряд "тик-так", имитирующий ход часов/using System;
using System.Threading;
class TickTock {
object lockOn = new object ; public void Tick(bool running) { lock(lockOn) {
if(!running) { // остановить часы ‘Monitor.Pulse(lockOn); // уведомить любые ожидающие потоки return;
}
Console.Write("тик ");
Monitor.Pulse(lockOn); // разрешить выполнение метода Tock Monitor.Wait(lockOn); // ожидать завершения метода Tock
}
}
public void Tock(bool running) { lock(lockOn) {
if(!running) { // остановить часы
Monitor.Pulse(lockOn); // уведомить любые ожидающие потоки return;
}
Console.WriteLine("так");
Monitor.Pulse(lockOn); // разрешить выполнение метода Tick Monitor.Wait(lockOn); // ожидать завершения метода Tick
}
}
}
class MyThread {
public Thread Thrd;
TickTock ttOb;
// Сконструировать новый поток.
public MyThread(string name, TickTock tt) {
Thrd = new Thread(this.Run); ttOb = tt;
Thrd.Name = name;
Thrd.Start; '
}
// Начать выполнение нового потока, void Run {
if(Thrd.Name == "Tick") {
for(int i=0; i<5; i++) ttOb.Tick(true); ttOb.Tick(false) ;
}
else {
for(int i=0; i<5; i++) ttOb.Tock(true); ttOb.Tock(false);
class TickingClock { static void Main {
TickTock tt = new TickTock ;
MyThread mtl = new MyThread("Tick", tt);
MyThread mt2 = new MyThread("Tock", tt) ; mtl.Thrd.Join; mt2.Thrd.Join;
Console.WriteLine("Часы остановлены");
}
}
Ниже приведен результат выполнения этой программы.
тик так тик так тик так тик так тик так
Часы остановлены
Рассмотрим эту программу более подробно. В методе Main создается объект tt типа TickTock, который используется для запуска двух потоков на выполнение. Если в методе Run из класса MyThread обнаруживается имя потока Tick, соответствующее ходу часов "тик", то вызывается метод Tick . А если это имя потока Tock, соответствующее ходу часов "так", то вызывается метод Tock . Каждый из этих методов вызывается пять раз подряд с передачей логического значения true в качестве аргумента. Часы идут до тех пор, пока этим методам передается логическое значение true, и останавливаются, как только передается логическое значение false.
Самая важная часть рассматриваемой здесь программы находится в методах Tick и Tock . Начнем с метода Tick , код которого для удобства приводится ниже.
public void Tick(bool running) { lock(lockOn) {
if(!running) { // остановить часы