Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Мониторы






Оператор lock фактически является надстройкой над классом Monitor. Запись:

lock(locker) {< критическая секция> }

можно рассматривать как краткую форму следующей записи:

Monitor.Enter(locker)

try

{< критическая секция> }

finally { Monitor.Exit(locker)}

Статический метод Enter класса Monitor закрывает критическую секцию, погруженную в try-блок, ссылочным объектом locker. Семантика такая же, как и у оператора lock. Все остальные потоки, пытающиеся войти в критическую секцию, закрытую ключом locker, будут выстраиваться в очередь, ожидая, пока секция не будет открыта. При любом завершении try-блока выполняется блок finally, снимающий блокировку.

У класса Monitor есть и другие методы, позволяющие организовать блокировку. Класс Monitor предоставляет метод TryEnter, имеющий следующий синтаксис:

public static bool TryEnter(

Object obj,

int millisecondsTimeout

)

Метод представляет функцию, возвращающую значение true, если за время ожидания, заданное параметром millisecondsTimeout, произошел вход в критическую секцию. Такая форма входа в критическую секцию нам уже знакома по описанию класса ReaderWriterLockSlim. Метод TryEnter перегружен и имеет еще две формы вызова, немногим отличающимся по семантике.

У класса Monitor есть еще три важных метода - Wait, Pulse, PulseAll. Эти методы вызываются внутри критической секции. Они взаимосвязаны и позволяют двум или нескольким потокам синхронизировать свою работу, посылая друг другу уведомления.

Пусть, выполняя действия в критической секции, поток обнаруживает, что другой поток должен выполнить некоторую обработку закрытого ресурса. В этой ситуации поток должен приостановить свою работу, освободить временно ресурс, чтобы дать другому потоку провести необходимую обработку, а затем уведомить приостановленный поток, что он может продолжить работу. Методы Wait - Pulse позволяют реализовать описанный сценарий. Метод Wait позволяет приостановить работу потока в критической секции. Метод Pulse посылает уведомление, позволяющее приостановленному потоку продолжить выполнение. Метод PulseAll позволяет продолжить выполнение всем приостановленным потокам.

Метод Wait перегружен, и мы рассмотрим только основной его вариант, имеющий следующий синтаксис:

public static bool Wait(object obj);

Параметр obj задает синхронизирующий объект, закрывающий критическую секцию. Обычно метод не использует возвращаемое значение и вызывается как оператор, а не как функция. Точная семантика метода такова. Метод освобождает синхронизирующий объект, поток прерывает работу и становится в специальную очередь ожидания уведомления. Когда другой метод, захвативший освобожденный объект синхронизации, выполняет метод Pulse, то первый метод из очереди ожидания переводится в очередь готовых к исполнению потоков. Когда настает черед выполняться методу, то восстанавливается его состояние, восстанавливаются все ранее сделанные блокировки и метод продолжает работать.

Метод Pulse имеет следующий синтаксис:

public static void Pulse(object obj);

При выполнении метода уведомляется очередь ожидания потоков с синхронизирующим объектом obj. В результате поток из этой очереди переходит в состояние готовность. Когда поток, вызвавший метод Pulse, освободит блокировку, то готовый поток продолжит выполнение.

Кооперация методов Wait - Pulse позволяет решать многие задачи взаимодействия потоков, которые невозможно решить другими способами.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.