Книга: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Синхронизация с помощью ключевого слова lock в C#

Синхронизация с помощью ключевого слова lock в C#

Первой из возможностей, которую вы можете применить в C# для синхронизации доступа к совместно используемым ресурсам, является использование ключевого слова lock. Это ключевое слово позволяет определить контекст операторов, которые должны синхронизироваться между потоками. В результате входящие потоки не смогут прервать текущий поток, пока он выполняет свою работу. Ключевое слово lock требует, чтобы вы указали маркер (объектную ссылку), который потребуется потоку для входа в пределы контекста lock. При блокировке метода уровня экземпляра можно использовать просто ссылку на текущий тип.

// Использование текущего объекта в качестве маркера потока.
lock(this) {
 // Весь программный код в этом контексте оказывается
 // устойчивым в отношении потоков.
}

При внимательном изучении метода PrintNumbers() становится ясно, что совместно используемым ресурсом, за доступ к которому соперничают потоки, является окно консоли. Поместите в рамки соответствующего контекста блокировки все операторы взаимодействии с типом Console так, как показано ниже.

public void PrintNumbers() {
 lock (this) {
  // Вывод информации Thread.
  Console.WriteLine("-› {0} выполняет PrintNumbers()", Thread.CurrentThread.Name);
  // Вывод чисел.
  Console.Write("Ваши числа": ");
  for (int i = 0; i ‹ 10; i++) {
   Random r = new Random();
   Thread.Sleep(1000 * r.Next(5));
   Console.Write(i + ", ");
  }
  Console.WriteLine();
 }
}

Тем самым вы создадите метод, который позволит текущему потоку завершить выполнение своей задачи. Как только поток вступит в контекст блокировки, соответствующий маркер блокировки (в данном случае эта ссылка на текущий объект) станет недоступным другим потокам, пока блокировка не будет снята в результате выхода потока из контекста блокировки. Например, если маркер блокировки получает поток А, то другие потоки не смогут войти в контекст до тех пор, пока поток А не освободит маркер блокировки.

Замечание. Если пытаться блокировать программный код в статическом методе, вы, очевидно, не можете использовать ключевое слово this. Но в этом случае можно передать объект System.Type соответствующего класса с помощью оператора C# typeof.

Если снова выполнить это приложение, вы увидите, что теперь каждый поток получает возможность закончить свою работу (рис. 14.10).


Рис. 14.10. Конкуренция в действии, третья попытка

Исходный код. Проект MultiThreadedPrinting размещен в подкаталоге, соответствующем главе 14.

Оглавление книги


Генерация: 1.216. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз