|
Ключовата дума lock маркира блок от оператори като критична зона, като взема 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.lock не може да заключи нулева стойност Обект може да сочи към null, но null не е необходимо да бъде освободен. (Виж също: Разбиране на пълната нулева) 2.заключване не може да заключва типа струн, въпреки че е и референтен тип. Защото типът струна се "задържа" от CLR Това означава, че има само един инстанция на даден низ в цялата програма и същият обект представлява този текст във всички нишки на всички работещи домейни на приложенията. Следователно, докато заключване е поставено върху низ със същото съдържание навсякъде в процеса на приложение, всички инстанции на този низ в приложението ще бъдат заключени. Затова е най-добре да заключвате частни или защитени членове, които няма да бъдат задържани. 3. заключване обектът е границата на паметта на програмен блок 4. Типът стойност не може да бъде заключен, защото "обектът е освободен" в червено в предишния текст, а типът стойност не е референтен тип 5.заключване избягва заключването на публични типове или обекти, които не са контролирани от програмата. Например, ако екземплярът е публично достъпен, lock(this) може да бъде проблематичен, защото неконтролираният код също може да заключи обекта. Това може да доведе до задънени заключения, при които две или повече нишки чакат, за да освободят един и същ обект. Заключването на публични типове данни (за разлика от обекти) също може да причини проблеми по същата причина. При използване на lock(this), стойността на променливата на член на класа може да бъде променена от метод, който не е в критичната зона
Сценарий на приложение: Често се използва за предотвратяване на несигурни изключения в стойността на публичните променливи, причинени от многонишкови операции, с цел гарантиране на сигурността на операциите
|