這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1、定義:單例對象的類必須保證只有一個執行個體存在,全域有唯一介面訪問。
2、分類:
- 懶漢方式:指全域的單例執行個體在第一次被使用時構建。
- 餓漢方式:指全域的單例執行個體在類裝載時構建。
3、實現:
(1)懶漢方式
1 type singleton struct{}2 var ins *singleton3 func GetIns() *singleton{4 if ins == nil {5 ins = &singleton{}6 }7 return ins8 }
缺點:非安全執行緒。當正在建立時,有線程來訪問此時ins = nil就會再建立,單例類就會有多個執行個體了。
(2)餓漢方式
1 type singleton struct{}2 var ins *singleton = &singleton{}3 func GetIns() *singleton{4 return ins5 }
缺點:如果singleton建立初始化比較複雜耗時時,載入時間會延長。
(3)懶漢加鎖
1 type singleton struct{} 2 var ins *singleton 3 var mu sync.Mutex 4 func GetIns() *singleton{ 5 mu.Lock() 6 defer mu.Unlock() 7 8 if ins == nil { 9 ins = &singleton{}10 }11 return ins12 }
缺點:雖然解決並發的問題,但每次加鎖是要付出代價的
(4)雙重鎖
1 type singleton struct{} 2 var ins *singleton 3 var mu sync.Mutex 4 func GetIns() *singleton{ 5 if ins == nil { 6 mu.Lock() 7 defer mu.Unlock() 8 if ins == nil { 9 ins = &singleton{}10 }11 }12 return ins13 }
避免了每次加鎖,提高代碼效率
(5)sync.Once實現
1 type singleton struct{}2 var ins *singleton3 var once sync.Once4 func GetIns() *singleton {5 once.Do(func(){6 ins = &singleton{}7 })8 return ins9 }