Шаблон 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?
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-рассылки, что вызвало дублирующие письма.