Что именно передается или используется в механизме блокировки (lock) в многопоточном программировании?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
В lock передается не «сам поток», а объект, который используется как монитор синхронизации. Важен именно общий и стабильный объект, одинаковый для всех потоков, которые должны взаимно исключать доступ. В C# lock гарантирует, что в критическую секцию одновременно войдет только один поток.
Определение:
lock в C# — это синтаксический сахар над Monitor.Enter / Monitor.Exit. В качестве аргумента используется ссылка на объект, по которому выполняется синхронизация. Пока один поток держит этот объект под блокировкой, другие потоки, пытающиеся захватить тот же объект, будут ждать.
Обычно для этого используют отдельный приватный объект, а не this, не строковые литералы и не публично доступные объекты. Это снижает риск внешней блокировки и взаимных зависаний.
Пример использования:
public class Counter
{
private readonly object _sync = new object();
private int _value;
public void Increment()
{
lock (_sync)
{
_value++;
}
}
public int Value => _value;
}
Здесь _sync — это объект-монитор. Если несколько потоков одновременно вызовут Increment(), они будут заходить в блок lock по очереди.
Пояснение кода:
Код нужен, потому что механизм lock лучше всего объясняется на простом примере.
- Создается приватный объект
_sync, который никто снаружи не использует. - Метод
Increment()входит в критическую секцию черезlock (_sync). - Первый поток захватывает монитор объекта
_syncи выполняет_value++. - Остальные потоки, которые пришли в
lock (_sync), блокируются до освобождения монитора. - После выхода из блока
lockмонитор освобождается автоматически.
Так обеспечивается атомарность операции увеличения счетчика: без блокировки два потока могли бы одновременно прочитать одно и то же значение и потерять одно из увеличений.
Ключевые моменты:
- В
lockпередается объект, а не поток и не число. - Один и тот же объект должен использоваться всеми потоками, которым нужна общая синхронизация.
- Для блокировки лучше брать private readonly object.
- Не стоит блокироваться на
this,typeof(...)и строковых литералах — это может привести к внешним конфликтам. lockзащищает только код внутри критической секции, а не весь объект целиком.- В C#
lockавтоматически освобождает монитор при выходе из блока, даже при исключении.