- •Оглавление
- •Класс Thread. Общая информация.
- •Thread – составляющие
- •Свойства
- •1) В следующем примере кода показаны простейшие функциональные возможности работы с потоками.
- •2)Пример изменения и использования свойств Priotiry, Name, CurrentThread
- •3) Создание потоков в фоновом режиме. Использование свойства IsBackground.
- •4) Ключевое слово lock
- •Interrupt(), Sleep(), SpinWait(), Join()
- •Класс Process Общая информация.
- •Process – составляющие Свойства
- •Примеры:
- •Класс WaitHandle Общая информация.
- •WaitHandle – составляющие Поля
- •Свойства
- •Класс Mutex Общая информация.
- •Mutex – составляющие Свойства
- •Примеры
- •Класс AutoResetEvent Общая информация.
- •AutoResetEvent – составляющие Методы
- •Примеры
- •Класс ManualResetEvent Общая информация.
- •ManualResetEvent – составляющие Методы
- •Примеры
- •Класс Monitor Общая информация.
- •Monitor – составляющие Методы
- •Класс Semaphore
- •Список литературы
Класс Monitor Общая информация.
Описание:
Предоставляет механизм для синхронизации доступа к объектам.
Класс Monitor контролирует доступ к объектам, предоставляя блокировку объекта одному потоку. Блокировки объектов предоставляют возможность ограничения доступа к части кода, обычно называемой критической секцией. Пока поток владеет блокировкой для объекта, никакой другой поток не может ею завладеть. Можно также использовать Monitor для того, чтобы убедиться, что ни один поток не имеет доступа к секции кода приложения, выполняющейся владельцем блокировки, пока другой поток не будет выполнять код, используя другой объект с блокировкой.
Следует использовать класс Monitor для блокировки объектов (т. е. ссылочные типы, а не скалярные). Подробные сведения см. в методе Enter и основном разделе Monitor.
Monitor имеет следующие свойства:
Связывается с объектом по требованию.
Он несвязан, что означает, что он может быть вызван непосредственно из любого контекста.
Невозможно создать экземпляр класса Monitor.
Следующая информация хранится для каждого синхронизированного объекта:
Ссылка на поток, который в данный момент владеет блокировкой.
Ссылка на очередь готовности, которая содержит потоки, готовые получить блокировку.
Ссылка на очередь ожидания, содержащую потоки, ожидающие уведомления об изменении состояния объекта с блокировкой.
Иерархия:
System.Object System.Threading.Monitor
Определение:
[C#]
public sealed class Monitor
Потокобезопасность:
Этот тип можно использовать в многопоточных операциях.
Monitor – составляющие Методы
|
Получает эксклюзивную блокировку указанного объекта. |
|
Освобождает эксклюзивную блокировку указанного объекта. |
|
Уведомляет поток в очереди готовности об изменении состояния объекта с блокировкой. |
|
Уведомляет все ожидающие потоки об изменении состояния объекта. |
|
Пытается получить эксклюзивную блокировку указанного объекта. |
|
Освобождает блокировку объекта и блокирует текущий поток до тех пор, пока тот не получит блокировку снова. |
Примеры:
Демонстрация использования метода Pulse
using System;
using System.Threading;
using System.Collections;
namespace MonitorCS1
{
class MonitorSample
{
const int MAX_LOOP_TIME = 1000;
Queue m_smplQueue;
public MonitorSample()
{
m_smplQueue = new Queue();
}
public void FirstThread()
{
int counter = 0;
lock (m_smplQueue)
{
while (counter < MAX_LOOP_TIME)
{
//Ждем,очередб занята
Monitor.Wait(m_smplQueue);
//Добавляем элемент
m_smplQueue.Enqueue(counter);
//Убираем ожтдающий поток
Monitor.Pulse(m_smplQueue);
counter++;
}
}
}
public void SecondThread()
{
lock (m_smplQueue)
{
//Убираем ожтдающий поток
Monitor.Pulse(m_smplQueue);
//Ждем в цикле пока очередь не освободиться
//Выход по таймауту когда первый поток остановиться
while (Monitor.Wait(m_smplQueue, 1000))
{
//Вытаскиваем первый элемент
int counter = (int)m_smplQueue.Dequeue();
//Вывод первого элемента на консоль
Console.WriteLine(counter.ToString());
//Убираем ожтдающий поток
Monitor.Pulse(m_smplQueue);
}
}
}
//Возвращает число элементов в очереди
public int GetQueueCount()
{
return m_smplQueue.Count;
}
static void Main(string[] args)
{
//Создаем объект MonitorSample
MonitorSample test = new MonitorSample();
//Создаем первый поток
Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
//Создаем второй поток
Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
//Запскаем потоки
tFirst.Start();
tSecond.Start();
//Ожидаем окончания обоих потоков
tFirst.Join();
tSecond.Join();
//Печатаем число элементов в очереди
Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
}
}
}