Ответ
В .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); // Явное освобождение
}
}
}
Ключевые различия
- Удобство и безопасность:
lockпроще и безопаснее, так как компилятор сам генерирует корректный код освобождения вfinally. - Гибкость:
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.