這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
單例模式,是一種常用的軟體設計模式,在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個執行個體且該執行個體易於外界訪問,從而方便對執行個體個數的控制並節約系統資源。
1. 懶漢模式(Lazy Loading)
懶漢模式是開源項目中使用最多的一種,最大的缺點是非安全執行緒的
type singleton struct {}// privatevar instance *singleton// publicfunc GetInstance() *singleton { if instance == nil { instance = &singleton{} // not thread safe } return instance}
2. 帶鎖的單例模式
type singleton struct {}var instance *singletonvar mu sync.Mutexfunc GetInstance() *singleton { mu.Lock() defer mu.Unlock() if instance == nil { instance = &singleton{} // unnecessary locking if instance already created } return instance}
這裡使用了Go的sync.Mutex,其工作模型類似於Linux核心的futex對象,具體實現極其簡單,效能也有保證
初始化時填入的0值將mutex設定在未鎖定狀態,同時保證時間開銷最小
這一特性允許將mutex作為其它對象的子物件使用
3. 帶檢查鎖的單例模式
if instance == nil { // <-- Not yet perfect. since it's not fully atomic mu.Lock() defer mu.Unlock() if instance == nil { instance = &singleton{} } } return instance}
這是一個不錯的方法,但是還並不是很完美。因為編譯器最佳化沒有檢查執行個體儲存狀態。如果使用sync/atomic包的話 就可以自動幫我們載入和設定標記。
import "sync"import "sync/atomic"var initialized uint32...func GetInstance() *singleton { if atomic.LoadUInt32(&initialized) == 1 { return instance } mu.Lock() defer mu.Unlock() if initialized == 0 { instance = &singleton{} atomic.StoreUint32(&initialized, 1) } return instance}
4.比較好的一種方式sync.Once
import ( "sync") type singleton struct {} var instance *singletonvar once sync.Once func GetInstance() *singleton { once.Do(func() { instance = &singleton{} }) return instance}
引文:
https://xiequan.info/go%E7%9A%84%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/