1. 概述
指目標(biāo)類(Class)只有一個(gè)實(shí)例對(duì)象(Object),并且向使用該對(duì)象的客戶端提供訪問單例的全局方法。
1.1 目的
- 保證類只有一個(gè)實(shí)例
- 有方法能讓外部訪問到該實(shí)例
1.2 實(shí)現(xiàn)方式
懶漢式
在第一次調(diào)用單例對(duì)象時(shí)創(chuàng)建該對(duì)象,這樣可以避免不必要的資源浪費(fèi)餓漢式
在程序啟動(dòng)時(shí)就創(chuàng)建單例對(duì)象,這樣可以提高程序的運(yùn)行效率雙重檢查鎖
通過加鎖來保證同一時(shí)刻只有一個(gè)線程可以創(chuàng)建單例對(duì)象
2. 代碼示例
2.1 設(shè)計(jì)
以一個(gè)餓漢式模式為例
- 定義一個(gè)單例對(duì)象
king- 它的
Get()方法為外部提供訪問
- 它的
- 聲明一個(gè)變量
ourKing,它的類型是單例對(duì)象king - 定義一個(gè)函數(shù)
CreateKing()用來實(shí)例化ourKing - 定義初始化函數(shù),調(diào)用函數(shù)
CreateKing()實(shí)例化ourKing - 調(diào)用
- 使用
ourKing的Get()方法訪問單例對(duì)象 - 再次調(diào)用
CreateKing()實(shí)例化ourKing,并訪問單例對(duì)象- 結(jié)果沒有變化,說明第二次實(shí)例化沒有執(zhí)行
- 使用
如果使用懶漢式模式,在main()函數(shù)調(diào)用CreateKing()函數(shù)即可
2.2 代碼
- han包
package main
import (
"fmt"
"sync"
)
// 定義單例對(duì)象
type king struct {
Name string
}
// 提供一個(gè)方法訪問單例對(duì)象
func (k *king) Get() {
fmt.Printf("%s is king\n", k.Name)
}
var (
//保證后邊創(chuàng)建函數(shù)只能執(zhí)行一次
once sync.Once
//聲明單一個(gè)變量類型是單例對(duì)象
ourKing *king
)
func init() {
//懶漢模式,啟動(dòng)時(shí)創(chuàng)建一個(gè)實(shí)例
CreateKing("漢獻(xiàn)帝")
}
// 定義一個(gè)創(chuàng)建單例對(duì)象的函數(shù)
func CreateKing(name string) (k *king) {
once.Do(func() {
ourKing = &king{
Name: name,
}
})
return ourKing
}
func main() {
//查看該啟動(dòng)時(shí)實(shí)例化的單例
ourKing.Get()
//再次實(shí)例化,并且訪問它,結(jié)果我們可以看見,沒有創(chuàng)建新實(shí)例
CreateKing("曹賊").Get()
}
- 輸出
獻(xiàn)帝 is king
獻(xiàn)帝 is king
可見
SetKing第二次并沒有實(shí)現(xiàn)。
