Sobes.tech
Назад к вопросам
Junior — Middle
62

Можно ли передать объект типа string в качестве механизма блокировки синхронизации?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Нет, string использовать как объект блокировки не стоит. string в .NET интернированы и могут неожиданно разделяться между разными частями программы. Для lock нужен приватный, недоступный извне объект.

Определение:

Механизм блокировки в C# должен опираться на отдельный объект синхронизации, который не используется нигде больше. string плох для этой роли, потому что строки являются ссылочными типами, могут быть интернированы и часто оказываются общими для разных мест кода. В результате разные потоки могут синхронизироваться на одном и том же объекте случайно.

Пример использования:

private readonly object _sync = new object();

public void UpdateState()
{
    lock (_sync)
    {
        // критическая секция
        // работа с общими данными
    }
}

Плохой пример:

private readonly string _sync = "lock";

public void UpdateState()
{
    lock (_sync)
    {
        // критическая секция
    }
}

Пояснение кода:

В первом примере создаётся отдельный приватный объект _sync, который используется только для синхронизации. Это безопасно, потому что никто извне не может случайно заблокировать тот же объект.

Во втором примере строка "lock" может быть интернирована CLR. Это значит, что одинаковая строка в другом месте приложения может ссылаться на тот же самый объект. Тогда блокировка становится непредсказуемой: можно получить лишнее ожидание, взаимные блокировки или проблемы с производительностью.

Ключевые моменты:

  • lock должен использовать приватный объект, предназначенный только для синхронизации.
  • string не подходит из-за интернирования и потенциального общего использования.
  • Нельзя блокироваться на this, typeof(...) и публичных объектах — по той же причине.
  • Хорошая практика: private readonly object _sync = new object();
  • Объект блокировки должен быть недоступен внешнему коду.