1. Почему замок и что такое заблокировано?
Когда мы используем потоки, самый эффективный способ, конечно, асинхронен, то есть каждый поток работает одновременно, без зависимости друг от друга и ожидания. Однако, когда разным потокам необходимо получить доступ к определённому ресурсу, требуется механизм синхронизации, то есть при чтении и записи одного и того же ресурса нужно сделать так, чтобы ресурс управлялся только одним потоком одновременно, чтобы каждая операция была эффективной и немедленной, то есть чтобы обеспечить атомарность её работы. lock — самый часто используемый метод синхронизации на C#, в формате lock(objectA){codeB}.
lock(objectA){codeB} кажется простым, но на самом деле имеет три значения, что необходимо для правильного использования: 1. ОбъектA заблокирован? Если нет, я заблокирую его, иначе жду, пока объект А не будет освобождён. 2. После блокировки другие потоки не могут вызывать codeB или использовать objectA во время выполнения codeB. 3. После выполнения codeB объект A и codeB могут быть доступны другими потоками.
2. Что случилось с замком (этим)?
Рассмотрим пример:
В потоке t1 LockMe вызывает lock(this), то есть c1 в основной функции, и при вызове lock(c1) в основном потоке он должен дождаться выполнения блока блокировки в t1, прежде чем обращаться к c1, то есть все операции, связанные с c1, нельзя выполнить, поэтому мы видим, что даже c1. DoNotLockMe() не выполняется.
|