ПрограммированиеBackend разработчик (VB.NET)

Как реализуется шаблон проектирования Singleton на Visual Basic, что стоит учитывать для потокобезопасности и в чем отличие между классическим и ленивым (lazy) вариантом реализации?

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Шаблон Singleton гарантирует, что у класса будет только один экземпляр, и предоставляет глобальную точку доступа к нему. В VB.NET чаще используют закрытый конструктор и статическое свойство для хранения единственного экземпляра:

Public Class Singleton Private Shared _instance As Singleton Private Sub New() ' Приватный конструктор End Sub Public Shared ReadOnly Property Instance() As Singleton Get If _instance Is Nothing Then _instance = New Singleton() End If Return _instance End Get End Property End Class

Потокобезопасность: В многопоточной среде возможно создание двух экземпляров при одновременном обращении. Решение: использовать блокировку или конструкцию Lazy(Of T):

' Ленивая потокобезопасная реализация Public Class Singleton Private Shared ReadOnly _instance As New Lazy(Of Singleton)(Function() New Singleton()) Private Sub New() End Sub Public Shared ReadOnly Property Instance() As Singleton Get Return _instance.Value End Get End Property End Class

Отличие:

  • Классический Singleton создаёт экземпляр при первом обращении, но требует ручной синхронизации.
  • "Ленивый" вариант использует встроенные механизмы .NET для создания экземпляра в потокобезопасном режиме.

Вопрос с подвохом.

Чем опасен такой код для реализации Singleton?

Public Shared ReadOnly Property Instance() As Singleton Get If _instance Is Nothing Then _instance = New Singleton() End If Return _instance End Get End Property

Ответ: В многопоточной среде возможна ситуация, когда два потока одновременно увидят, что _instance — Nothing, и оба создадут объект. Поэтому такой подход не является полностью потокобезопасным. Рекомендуется использовать Lazy(Of T) или SyncLock для блокировки.

Примеры реальных ошибок из-за незнания тонкостей темы.


История

ERP система: Singleton логгер при запуске из сервисов иногда создавался дважды, логи терялись. Причина — отсутствие синхронизации в свойстве, хотя приложение было многопоточным.


История

Windows Forms приложение: В проекте вынесли работу с базой данных в Singleton, но не реализовали ленивую инициализацию. При старте приложения происходил тяжелый коннект, замедляя загрузку UI для всех.


История

Плагин журналистской платформы: Попытались использовать статическую переменную в модуле для Singleton, не защищённую от многопоточного доступа, в результате в горячей фазе нагрузки появилось несколько экземпляров обработчика email-рассылки, что вызвало дублирующие письма.