在Go語言中實現單例模式通常有幾種方法。單例模式的目的是確保一個類只有一個例項,並提供一個全域性訪問點來訪問這個例項。下面是幾種常見的實現方式:
1. 基於包級別的變數(懶漢式)
這是最簡單的一種實現方式,透過在包初始化時建立單例物件。
1 package singleton 2 3 import "sync" 4 5 type Singleton struct { 6 // 單例物件的屬性 7 } 8 9 var instance *Singleton 10 var once sync.Once 11 12 func GetInstance() *Singleton { 13 once.Do(func() { 14 instance = &Singleton{} 15 }) 16 return instance 17 }
在這個例子中,once.Do() 確保了 instance 只會被初始化一次。sync.Once 是 Go 語言提供的同步原語,用於確保某個操作只執行一次。
2. 餓漢式
如果單例物件的初始化不需要引數,且不依賴於其他資源,可以在宣告時直接初始化,這種方式稱為“餓漢式”。
1 package singleton 2 3 type Singleton struct { 4 // 單例物件的屬性 5 } 6 7 var instance = &Singleton{} 8 9 func GetInstance() *Singleton { 10 return instance 11 }
這種方式在程式啟動時就完成了單例物件的建立,因此是執行緒安全的,但是可能造成資源的浪費,因為無論是否需要,都會在程式啟動時建立物件。
3. 使用 sync.Mutex 實現執行緒安全(懶漢式)
如果沒有 sync.Once,或者你需要更細粒度的控制,可以使用 sync.Mutex 來保證執行緒安全。
1 package singleton 2 3 import ( 4 "sync" 5 ) 6 7 type Singleton struct { 8 // 單例物件的屬性 9 } 10 11 var ( 12 instance *Singleton 13 mutex sync.Mutex 14 ) 15 16 func GetInstance() *Singleton { 17 if instance == nil { 18 mutex.Lock() 19 defer mutex.Unlock() 20 if instance == nil { 21 instance = &Singleton{} 22 } 23 } 24 return instance 25 }
這裡使用了雙重檢查鎖定模式(Double-Check Locking Pattern),確保了多執行緒環境下的安全性,同時避免了每次呼叫 GetInstance 函式時都加鎖,提高了效能。
以上就是Go語言中實現單例模式的幾種常見方式。選擇哪種方式取決於你的具體需求,比如是否需要延遲初始化、是否需要執行緒安全等。