单例模式保证一个类只有一个实例,并提供对该实例的全局访问。在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
区别:
这种代码实现单例有什么危险?
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系统: 在服务启动时,单例日志记录器有时会被创建两次,日志丢失。原因是属性中缺少同步,尽管应用程序是多线程的。
故事
Windows Forms应用程序: 项目中将与数据库的工作移到单例中,但未实现懒惰初始化。应用程序启动时发生了重负载连接,减慢了所有用户界面的加载。
故事
新闻平台插件: 尝试在模块中使用未保护的静态变量来实现单例,导致在高负载阶段出现多个电子邮件处理程序实例,造成邮件重复发送。