В чем разница между Lock и Monitor в .NET?

«В чем разница между Lock и Monitor в .NET?» — вопрос из категории Многопоточность, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В .NET lock — это ключевое слово языка C#, а Monitor — класс в пространстве имен System.Threading. lock является синтаксическим сахаром над методами Monitor.Enter и Monitor.Exit.

Lock (Синтаксический сахар)

lock автоматически создает блок try-finally, гарантируя освобождение блокировки даже при возникновении исключения.

private readonly object _syncObject = new object();

public void ThreadSafeMethod()
{
    lock (_syncObject)
    {
        // Критическая секция. Доступен только одному потоку.
        SharedResource.Count++;
    }
}

Monitor (Более гибкий низкоуровневый API)

Класс Monitor предоставляет прямой контроль и дополнительные возможности, которых нет у lock.

private readonly object _syncObject = new object();

public void ThreadSafeMethod()
{
    bool lockTaken = false;
    try
    {
        Monitor.Enter(_syncObject, ref lockTaken); // Явный захват
        // Критическая секция
        SharedResource.Count++;
    }
    finally
    {
        if (lockTaken)
        {
            Monitor.Exit(_syncObject); // Явное освобождение
        }
    }
}

Ключевые различия

  1. Удобство и безопасность: lock проще и безопаснее, так как компилятор сам генерирует корректный код освобождения в finally.
  2. Гибкость: Monitor предоставляет методы для сложных сценариев синхронизации:
    • Monitor.Wait(object obj): Временно освобождает блокировку и ожидает сигнала.
    • Monitor.Pulse(object obj) и Monitor.PulseAll(object obj): Уведомляют один или все ожидающие потоки.
    • Monitor.TryEnter(object obj, int millisecondsTimeout): Пытается захватить блокировку с таймаутом, что помогает избежать взаимных блокировок (deadlock).

Вывод: Используйте lock для простых критических секций. Прибегайте к Monitor напрямую, когда нужны таймауты (TryEnter) или сложные шаблоны взаимодействия потоков, такие как Producer-Consumer.