Большая часть проблемы - то, что программисты просто неясны о том, когда блокировки необходимы, который я, надо надеяться, теперь убрал. Одно только это понимание не достаточно, как бы то ни было. Ужасно просто сделать ошибки, потому что это только берет пропущенную блокировку того, чтобы ввести гонки. Требуете сильных методологий, что помощь избегает simple-common. Однако даже лучшие текущие методы требуют, чтобы значительный уход применил их хорошо.
Один из самых простых и самых полезных методов для методического блокирования является понятием монитора. Основная идея состоит в том, чтобы осуществить контрейлерные перевозки на абстракции данных, которая уже присутствует в ориентированном на объект дизайне. Рассмотрите пример хеш-таблицы. В хорошо разработанном классе будет уже иметь место, что клиенты только получают доступ к его внутреннему состоянию, называя его методы случая. Если блокировка взята на входе в какой-либо метод случая и выпущена на выходе, есть систематический способ удостовериться, чтобы все доступы к внутренним данным (поля случая) только произошли, когда блокировка проводится, как показано в рисунке 6. Классы, которые следуют этому протоколу, называют мониторами.
Это не случайно, что названием блокировки в.NET Структуре является Система. Пронизывание. Монитор. Этот тип был в частности адаптирован, чтобы поддерживать понятие монитора. Причина.NET блокировки воздействует на Систему. Объект состоит в том, чтобы сделать создание мониторов проще. Эффективно, у каждого объекта есть встроенная блокировка, которая может использоваться, чтобы защитить ее данные о случае. Включая организацию каждого метода случая в блокировке (этот) отчет, монитор может быть сформирован. Есть даже специальный признак, [MethodImpl (MethodImplAttributes. Синхронизированный)], который может быть помещен в методы случая, чтобы автоматически вставить блокировку (этот) отчет. Далее.NET блокировки reentrant, означая, что нить, которая ввела блокировку, может ввести блокировку снова без блокирования. Это позволяет методам называть другие методы на том же классе, не вызывая тупик, который обычно происходил бы.
В то время как полезный (и простой написать использование.NET), мониторы далеки от панацеи для блокирования. Если они используются без разбора, они могут привести или к слишком мало или к слишком много блокирования. Рассмотрите заявление, которое использует хеш-таблицу, которая, как показывают в рисунке 6, внедрила высокоуровневую работу под названием Дебет, который переводит деньги от одного счета до другого. Дебетовый метод использует метод Находки на Hashtable, чтобы восстановить два счета и метод Обновления, чтобы фактически выполнить передачу. Поскольку Hashtable является монитором, звонки Найти и Обновить, как гарантируют, будут атомными. К сожалению, Дебетовый метод требует больше, чем эта гарантия валентности. Если другой нить обновления один из счетов между двумя звонками Обновить тот Дебет делает, Дебет может быть неправильным. Монитор выполнял прекрасную работу защиты Hashtable в единственном звонке, но инвариант, необходимый по нескольким звонкам, был пропущен, потому что слишком мало блокирования было сделано.
Фиксация гонки в Дебетовом методе с монитором может привести к слишком большому блокированию. То, что необходимо, является блокировкой, которая защищает всю память, которую Дебетовый метод использует и может быть проведен на время метода. Если бы использовали монитор, чтобы сделать это, то это походило бы на класс Accounts, показанный в рисунке 7. Каждая высокоуровневая работа как Дебет или Кредит возьмет блокировку на Счетах прежде, чем выполнить ее работу, таким образом предоставляя необходимое взаимное исключение. Создание монитора Accounts фиксирует гонку, но теперь подвергает сомнению стоимость блокировки на Hashtable. Если все доступы к Счетам (и поэтому Hashtable) берут блокировку Accounts, то взаимное исключение для доступов к Hashtable (который является частью Счетов) уже гарантируют. Если это так, то не требуется для накладных расходов наличия блокировки для Hashtable. Слишком много блокирования было сделано.