Класс System: :Threading: :Monitor (Система::Организация поточной об-работки::Монитор) позволяет потокам синхронизировать доступ к объектам, чтобы избежать нарушения целостности данных и неопределенного поведения вследствие соперничества между потоками. Шаг 2 из примера Threading (Организация поточной обработки) демонстрирует использование класса Monitor (Монитор) с указателем this экземпляра HotelBroker.
ReservationResult *Reserve(Reservation *res) // Резервирование
{
Console::WriteLine(
"Thread {0} trying to enter Broker::Reserve",
// "Поток {0} пытается войти в Брокер::Резерв",
Thread::CurrentThread-> // Поток
GetHashCode() .ToString ()); Monitor::Enter(this); // Монитор::Войти
. . . (спорный код потока здесь) Monitor::Exit(this); // Выход
return result; // результат
}
Потоку, который первым вызовет метод Monitor: : Enter (this), будет разрешено выполнить метод Reserve (Резерв), потому что он овладеет замком метода Monitor (Монитор) с помощью указателя this. Потоки, пробующие выполнить те же действия, должны будут ожидать, пока первый поток не разблокирует замок с помощью метода Monitor: :Exit (this). После этого и другие потоки смогут вызвать Monitor::Enter(this) и овладеть замком.
Поток может вызывать Monitor: :Enter (Монитор::Войти) несколько раз, но каждый вызов должен быть скомпенсирован вызовом Monitor: :Exit (Монитор::Выйти). Если поток пытается овладеть замком, но не хочет заблокировать себя, то он может использовать метол Monitor::TryEnter.
Теперь, когда мы обеспечили синхронизацию, случай, идентичный испытанному в шаге 1, не приведет к повторному резервированию одного и того же гостиничного номера на одно и то же время. Обращаем внимание читателя на то, сколько времени второй поток не может начать выполнение метода Reserve (Резерв) до тех пор, пока первый поток, который начал выполнение этого метода раньше, не покинет критическую секцию. Это решает нашу проблему конкуренции между потоками и устанавливает правило, согласно которому один и тот же номер гостиницы не может быть забронирован двумя клиентами на ту же самую дату.
Added Boston Presidential Hotel with one room.
Thread 3 starting a new thread.
Thread 5 starting.
Thread б starting.
Reserving for Customer 2 at the Boston Presidential Hotel on
12/13/2001 12:00:00 AM for I days
Thread 6 trying to enter Broker::Reserve
Thread 6 entered Broker::Reserve
Thread 6 finds the room is available in Broker::Reserve
Thread 6 left Broker::Reserve
Reservation for Customer 2 has been booked
Reservationld = 1
Reserving for Customer 1 at the Boston Presidential Hotel on
12/12/2001 12:00:00 AM for 3 days
Thread 5 trying to enter Broker::Reserve
Thread 5 entered Broker::Reserve
Reservation for Customer 1 could not be booked
Room not available
ReservationRate = 10000
ReservationCost = 10000
Comment = OK
Done !
Пере вод такой:
Добавлена Бостонская Президентская гостиница с одним номером.
Поток 3 стартовал новый поток.
Поток 5 стартовал.
Поток 6 стартовал.
Резервирование для Клиента 2 в Бостонской Президентской гостинице на
12/13/2001 12:00:00 AM в течение 1 дня
Поток 6 пытается войти в Брокер::Резерв
Поток 6 вошел в Брокер::Резерв
Поток 6 находит, что номер доступен в Брокер::Резерв
Поток 6 вышел из Брокер::Резерв
Резервирование для Клиента 2 было заказано
Reservationld = 1
Резервирование для Клиента 1 в Бостонской Президентской гостинице на
12/12/2001 12:00:00 AM в течение 3 дней
Поток 5 пытается войти в Брокер::Резерв
Поток 5 вошел в Брокер::Резерв
Резервирование для Клиента 1 не могло быть заказано
Номера не доступны
ReservationRate = 10000
ReservationCost = 10000
Комментарий = OK
Сделано!