VisualBasic構(gòu)建線程安全的Singleton

字號:

大抵而言,Singleton 模式應(yīng)該是設(shè)計模式中相當(dāng)常用的一種了。它能夠節(jié)省寶貴的 CPU 或內(nèi)存資源,避免不必要的創(chuàng)建對象開銷。然而,在多線程應(yīng)用中,對于那些非線程安全的數(shù)據(jù)庫組件,傳統(tǒng)的 Singleton 將容易造成不穩(wěn)定。如果使用 Synclock 進(jìn)行同步,性能損耗可能將更大,特別在并發(fā)訪問高的 ASP.net 應(yīng)用中。
    前十幾天和網(wǎng)友聊天的時候,他把 ThreadwiseSingleton 發(fā)給了我,我隨后改寫成泛型類。事實(shí)上,它基于 Threadslot 構(gòu)建,因此達(dá)到了線程隔離的效果。您需要傳入一個 Func(Of TResult) 完成初始化的工作。如果您的類中含有非托管資源,并無法預(yù)見可能的錯誤時,請使用一個 Try...Finally... 包裹將要運(yùn)行的程序。同時感到抱歉的是,拖延了很久很久才發(fā)出來。
    Imports System.Threading
    '''
    ''' 一個線程隔離的 Singleton。
    '''

    Public Class ThreadwiseSingletonClass ThreadwiseSingleton(Of T As IDisposable)
    Private Shared _Factory As Func(Of T)
    '''
    ''' 獲取構(gòu)建此實(shí)例的工廠類。
    '''

    Public Shared Property Factory()Property Factory() As Func(Of T)
    Get
    Return _Factory
    End Get
    Set(ByVal value As Func(Of T))
    _Factory = value
    End Set
    End Property
    '''
    ''' 獲得線程中的實(shí)例。
    '''

    Public Shared ReadOnly Property Instance()Property Instance() As T
    Get
    Dim threadSlot As LocalDataStoreSlot = Thread.GetNamedDataSlot(GetType(T).ToString)
    Dim threadSlotObj As Object = Thread.GetData(threadSlot)
    If threadSlotObj Is Nothing Then
    'Create singleton instance
    Dim ins As T = Factory.Invoke
    Thread.SetData(threadSlot, ins)
    Return ins
    Else
    Return DirectCast(threadSlotObj, T)
    End If
    End Get
    End Property
    '''
    ''' 私有的構(gòu)造函數(shù)。
    '''

    Private Sub New()Sub New()
    End Sub
    '''
    ''' 釋放此 Singleton 實(shí)例使用的資源。請不要直接調(diào)用 Instance.Dispose()。
    '''

    Public Shared Sub Dispose()Sub Dispose()
    Instance.Dispose()
    '放空槽
    Dim threadSlot As LocalDataStoreSlot = Thread.GetNamedDataSlot(GetType(T).ToString)
    Thread.SetData(threadSlot, Nothing)
    End Sub
    End Class