Singletonパターンは、クラスに1つのインスタンスのみが存在することを保証し、そのインスタンスへのグローバルなアクセスを提供します。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
スレッドセーフ性:
マルチスレッド環境では、同時にアクセスすることで2つのインスタンスが作成される可能性があります。解決策:ロックまたは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
答え: マルチスレッド環境では、2つのスレッドが同時に_instanceがNothingであることを確認して、両方がオブジェクトを作成するという状況が発生する可能性があります。そのため、このアプローチは完全にスレッドセーフではありません。Lazy(Of T)またはSyncLockを使用してロックを行うことをお勧めします。
物語
ERPシステム: サービスから起動する際、Singletonロガーが時々2回作成され、ログが失われました。理由は、プロパティ内に同期が欠如していたためですが、アプリケーションはマルチスレッドでした。
物語
Windows Formsアプリケーション: プロジェクト内でデータベースとの操作をSingletonに持ち込んだが、遅延初期化を実装しませんでした。アプリケーションの起動時に重い接続が行われ、全体のUIの読み込みが遅くなりました。
物語
ジャーナリストプラットフォームのプラグイン: Singletonのためにモジュール内にスレッドセーフでない静的変数を使用しようとした結果、負荷の高いフェーズでメール配信のハンドラのインスタンスが複数生成され、重複メールが発生しました。