|
Ключове слово блокування позначає блок операторів як критичну зону, беручи mutex для певного об'єкта, виконує оператор і потім звільняє блокування.
Оператор lock фактично використовує Monitor.Enter і Monitor.Exit, тобто Monitor.Enter(this) виконується при виконанні lock(this), а Monitor.Exit(this) — наприкінці завиткової розкладки. Що це означає? Для будь-якого об'єкта перша частина пам'яті — це адреса всіх методів, а друга — індекс. Він вказує на SyncBlock у SyncBlock Cache CLR. Що це означає? Тобто, коли ви виконуєте Monitor.Enter(Object), якщо індексне значення об'єкта від'ємне, виберіть SyncBlock із кешу SyncBlock і вмістіть його адресу в індекс об'єкта. Це завершує блокування, позначене об'єктом, і інші потоки хочуть знову виконати операцію Monitor.Enter(object), яка отримає індекс з позитивним об'єктом і чекає. Поки індекс не стане від'ємним, тобто потік використовує Monitor.Exit(object) для перетворення індексу на негативний. На що слід звертати увагу при використанні замка:
1.блокування не може заблокувати null значення Об'єкт може вказувати на null, але null не потрібно відпускати. (Див. також: Розуміння повного нуля) 2.lock не може заблокувати тип рядка, хоча він також є референсним типом. Тому що тип рядка «зависає» CLR Це означає, що в усій програмі є лише один екземпляр будь-якого рядка, і цей об'єкт представляє цей текст у всіх потоках усіх запущених доменів додатків. Отже, доки блокування розміщено на рядку з однаковим вмістом будь-де в процесі застосування, усі екземпляри цього рядка в додатку будуть заблоковані. Тому найкраще закривати приватних або захищених учасників, які не будуть збережені. 3. блокування об'єкта — це межа пам'яті блоку програми 4. Тип значення не може бути заблокований, оскільки «об'єкт звільнено» червоним у попередньому тексті, а тип значення не є референсним типом 5.Блокування уникає блокування публічних типів або об'єктів, які не контролюються програмою. Наприклад, якщо екземпляр публічно доступний, lock(this) може бути проблемним, оскільки неконтрольований код також може блокувати об'єкт. Це може призвести до глухих кутів, коли два або більше потоків чекають на звільнення одного й того ж об'єкта. Блокування публічних типів даних (на відміну від об'єктів) також може спричиняти проблеми з тієї ж причини. При використанні lock(this) значення змінної члена класу може змінюватися методом, який не знаходиться в критичній зоні
Сценарій застосування: Часто використовується для запобігання невизначеним виняткам у значенні публічних змінних, спричинених багатопотоковими операціями, щоб забезпечити безпеку операцій
|