TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2543 2.53K
День 2102. #ЗаметкиНаПолях
Использование Singleton в Многопоточных Сценариях. Окончание

Начало

3. Блокировка с двойной проверкой
Первая проверка: первая проверка на null. Если экземпляр не пуст, он возвращается. Эта проверка позволяет избежать накладных расходов на блокировку в большинстве вызовов после инициализации экземпляра.
Блокировка: если экземпляр null, получается блокировка.
Вторая проверка: внутри блокировки выполняется вторая проверка, т.к. другой поток мог инициализировать экземпляр между первой проверкой и получением блокировки. Если экземпляр всё ещё null после второй проверки, он создаётся.
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object lck = new object();

Singleton() {}

public static Singleton Instance
{
get
{
if (instance == null)
{
lock (lck)
{
if (instance == null)
instance = new Singleton();
}
}
}
return instance;
}
}

Это лучшее решение? Не совсем. Решение сложное и может вызвать проблемы, если его неправильно использовать.

4. Singleton с Lazy
Ленивая инициализация: класс Lazy автоматически обрабатывает ленивую инициализацию экземпляра Singleton. Экземпляр не создаётся, пока он действительно не понадобится. Lazy гарантирует, что экземпляр создаётся потокобезопасным способом, поэтому не нужно использовать блокировки или дважды проверять блокировку. Кроме того, код проще и удобнее для обслуживания, поскольку сложность синхронизации потоков инкапсулирована в классе Lazy.
public class Singleton
{
private static readonly Lazy<Singleton>
instance = new Lazy<Singleton>(
() => new Singleton());

private Singleton() {}

public static Singleton Instance
=> instance.Value;
}

Ключевые преимущества использования Lazy для реализации Singleton:
• Потокобезопасность: Lazy обрабатывает все сложности потокобезопасности, снижая риск ошибок.
• Производительность: как правило, более эффективно, так как не требует явной блокировки (которая может быть затратной).
• Простота: код намного чище и понятнее, что повышает удобство обслуживания.

Итого
Существует несколько других способов реализации этого шаблона. Lazy хорош с точки зрения производительности и ленивой работы, а также легко читаем. Это может быть хорошим стартом для начинающих изучать шаблон Singleton. Определённо стоит избегать первого способа, потому что он не потокобезопасен и может вызвать серьёзные проблемы в коде.

Источник: https://thecodeman.net/posts/how-to-use-singleton-in-multithreading
  • 👍 28
More from @netdeveloperdiary
  1. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  2. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  3. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  4. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  5. Oct 3, 2026Post #3360
  6. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →