23 Возможности библиотеки Task Parallel Library. Средства для взаимного исключения

Одно из основных назначений средств синхронизации заключается в организации взаимно исключительного доступа к разделяемому ресурсу. Изменения общих данных одним потоком не должны прерываться другими потоками. Фрагмент кода, в котором осуществляется работа с разделяемым ресурсом и который должен выполняться только в одном потоке одновременно, называется критической секцией.

public string data; 
void DoSomeWork1() 
{ 
  Thread.Name = "First"; 
  data = "AAAA"; 
  Console.WriteLine("Thread: {0}, Data: {1}",     Thread.Name, data); 
} 
 
void DoSomeWork2() 
{ 
  Thread.Name = "Second"; 
  data = "BBBB"; 
  Console.WriteLine("Thread: {0}, Data: {1}", 
    Thread.Name, data); 
 
} 

В этом фрагменте предполагается, что два потока изменяют значение общей переменной data. После внесения изменений поток выводит на экран новое значение data и имя потока. Отсутствие средств синхронизации могло бы привести к некорректному результату:

Thread: First, Data: BBBBB 
Thread: Second, Data: BBBBB 

Поток First внес свои изменения и собирался вывести сообщение, но второй поток успел вклиниться и изменить данные.

Выделение критической секции с помощью конструкции lock позволяет избежать такой ситуации:

lock(sync_obj) 
{ 
  data = "AAAA"; 
  Console.WriteLine("Thread #1 has changed 
      data to: {0}", data); 
} 

Когда один поток входит в критическую секцию (захватывает объект синхронизации), другой поток ожидает завершения всего блока (освобождения объекта синхронизации). Если заблокировано было несколько потоков, то при освобождении критической секции только один поток разблокируется и входит критическую секцию.

Для выделения критической секции с помощью конструкции lock необходимо указать объект синхронизации, который выступает в качестве идентификатора блокировки.