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

Основная идея паттерна Одиночка (Singleton) в том, что это класс, предназначенный для создания только одного экземпляра, и он обычно предоставляет простой способ доступа к этому экземпляру.

Как правило, Singletonы создаются без использования каких-либо параметров для создания экземпляра. Это необходимо для предотвращения осложнений, которые могут возникнуть при попытке создания второго экземпляра с другими параметрами. Общей характеристикой Singleton является их ленивое создание, то есть экземпляр не генерируется, пока он не потребуется впервые.

Рассмотрим варианты его реализации.

1. Базовый — не потокобезопасный
Это канонический пример реализации паттерна Singleton.
public sealed class Singleton
{
private static Singleton instance = null;

private Singleton() {}

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

Это не потокобезопасно. Может случиться так, что два потока одновременно проверят экземпляр на null и получат true. В результате каждый создаст экземпляр, что противоречит правилу наличия только одного экземпляра Singleton. Также возможно, что экземпляр будет создан до того, как произойдёт эта проверка, но другие потоки могут не увидеть этот новый экземпляр сразу, если не предпринять определённые шаги, чтобы убедиться, что они это сделают.

2. Используем lock
Сначала поток блокирует общий объект, а затем проверяет, был ли уже создан экземпляр. Если нет, он продолжает и создаёт экземпляр. Этот процесс гарантирует, что все чтения будут происходить после того, как будет получена блокировка, а все записи будут происходить до того, как она будет освобождена. Так только один поток сможет создать экземпляр, потому что пока один поток находится в процессе его создания, никакой другой поток не может войти в эту часть кода. К тому времени, как второй поток доберётся туда, первый уже создаст экземпляр, поэтому проверка на null вернёт false.
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object lck = new object();

Singleton(){}

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

Недостатком этого метода является то, что он может замедлить работу, поскольку требует блокировки каждый раз, когда требуется экземпляр.
А нужно ли блокировать каждый раз? Нет.

Окончание следует…

Источник:
https://thecodeman.net/posts/how-to-use-singleton-in-multithreading
  • 👍 5
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 →