Читаем C# 4.0: полное руководство полностью

    MyThread mt1 = new MyThread("Потомок #1", a);

    MyThread mt2 = new MyThread("Потомок #2", a);

    mt1.Thrd.Join();

    mt2.Thrd.Join();

  }

}

В данной программе блокируется вызов метода sa.Sum It(), а не сам метод SumIt(). Ниже приведена соответствующая строка кода, в которой осуществляется подобная блокировка.

// Заблокировать вызовы метода SumIt().

lock(sa) answer = sa.SumIt(a);

Объект sa является закрытым, и поэтому он может быть благополучно заблокирован. При таком подходе к синхронизации потоков данная программа дает такой же правильный результат, как и при первоначальном подходе.

Класс Monitor и блокировка

Ключевое слово lock на самом деле служит в C# быстрым способом доступа к средствам синхронизации, определенным в классе Monitor, который находится в пространстве имен System.Threading. В этом классе определен, в частности, ряд методов для управления синхронизацией. Например, для получения блокировки объекта вызывается метод Enter(), а для снятия блокировки — метод Exit(). Ниже приведены общие формы этих методов:

public static void Enter(object obj)

public static void Exit (object obj)

где obj обозначает синхронизируемый объект. Если же объект недоступен, то после вызова метода Enter() вызывающий поток ожидает до тех пор, пока объект не станет доступным. Тем не менее методы Enter() и Exit() применяются редко, поскольку оператор lock автоматически предоставляет эквивалентные средства синхронизации потоков. Именно поэтому оператор lock оказывается "более предпочтительным" для получения блокировки объекта при программировании на С#.

Впрочем, один метод из класса Monitor может все же оказаться полезным. Это метод TryEnter(), одна из общих форм которого приведена ниже.

public static bool TryEnter(object obj)

Этот метод возвращает логическое значение true, если вызывающий поток получает блокировку для объекта obj, а иначе он возвращает логическое значение false. Но в любом случае вызывающему потоку придется ждать своей очереди. С помощью метода TryEnter() можно реализовать альтернативный вариант синхронизации потоков, если требуемый объект временно недоступен.

Кроме того, в классе Monitor определены методы Wait(), Pulse() и PulseAll(), которые рассматриваются в следующем разделе.

<p>Сообщение между потоками с помощью методов Wait(), Pulse() и PulseAll()</p>

Рассмотрим следующую ситуацию. Поток T выполняется в кодовом блоке lock, и ему требуется доступ к ресурсу R, который временно недоступен. Что же тогда делать потоку T? Если поток T войдет в организованный в той или иной форме цикл опроса, ожидая освобождения ресурса R, то тем самым он свяжет соответствующий объект, блокируя доступ к нему других потоков. Это далеко не самое оптимальное решение, поскольку оно лишает отчасти преимуществ программирования для многопоточной среды. Более совершенное решение заключается в том, чтобы временно освободить объект и тем самым дать возможность выполняться другим потокам. Такой подход основывается на некоторой форме сообщения между потоками, благодаря которому один поток может уведомлять другой о том, что он заблокирован и что другой поток может возобновить свое выполнение. Сообщение между потоками организуется в C# с помощью методов Wait(), Pulse() и PulseAll().

Методы Wait(), Pulse() и PulseAll() определены в классе Monitor и могут вызываться только из заблокированного фрагмента блока. Они применяются следующим образом. Когда выполнение потока временно заблокировано, он вызывает метод Wait(). В итоге поток переходит в состояние ожидания, а блокировка с соответствующего объекта снимается, что дает возможность использовать этот объект в другом потоке. В дальнейшем ожидающий поток активизируется, когда другой поток войдет в аналогичное состояние блокировки, и вызывает метод Pulse() или PulseAll(). При вызове метода Pulse() возобновляется выполнение первого потока, ожидающего своей очереди на получение блокировки. А вызов метода PulseAll() сигнализирует о снятии блокировки всем ожидающим потокам.

Ниже приведены две наиболее часто используемые формы метода Wait().

public static bool Wait(object obj)

public static bool Wait(object obj, int миллисекунд_простоя)

Перейти на страницу:

Похожие книги

1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT
Adobe InDesign CS3
Adobe InDesign CS3

Книга посвящена верстке и макетированию в программе Adobe InDesign CS3. Помимо того что в ней описываются возможности программы, рассматриваются также принципы и традиции верстки, приводятся примеры решения типичных задач. Все это позволит читателю не только овладеть богатым инструментарием программы, но и грамотно применять его.Материал книги разделен на логические части: теоретические сведения, инструментарий программы, решение задач, – а также рассчитан на два уровня подготовки читателей – начинающих и опытных пользователей, что выгодно отличает книгу от других изданий. Это позволит применять ее как новичкам для знакомства с программой, так и пользователям со стажем для пополнения своих знаний.

Владимир Гавриилович Завгородний , Владимир Завгородний

Программирование, программы, базы данных / Программное обеспечение / Книги по IT
Разработка приложений в среде Linux. Второе издание
Разработка приложений в среде Linux. Второе издание

Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет СЃРѕР±РѕР№ отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из РґСЂСѓРіРёС… операционных систем. РџРѕРґСЂРѕР±но рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование СЃРІРѕР±одно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Р

Майкл К. Джонсон , Эрик В. Троан

Программирование, программы, базы данных