欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang基于sync.Once實現(xiàn)單例的操作代碼

 更新時間:2022年10月28日 11:14:17   作者:Hugo Lei  
這篇文章主要介紹了golang實現(xiàn)單例的操作代碼,本文介紹基于sync.Once的方式來實現(xiàn)單例,熟練掌握這種模式,并理解其底層原理,對大部分人來講已經(jīng)完全夠用了,需要的朋友可以參考下

在go里實現(xiàn)單例模式有多種方式:

  • 基于lock
  • 基于init函數(shù)
  • 基于sync.Once

本文介紹基于sync.Once的方式來實現(xiàn)單例,熟練掌握這種模式,并理解其底層原理,對大部分人來講已經(jīng)完全夠用了。

基于sync.Once實現(xiàn)單例

// 其他package也可見,在其他地方也可以new新對象
// 但是最終調(diào)用Conn()方法時,都是用的single這個單例
// 1
type Driver struct {
	// 小寫字母開頭,外部不可訪問,所以new個Driver新對象也沒用
	// 2
	conn string
}

// 全局變量,指針默認值為nil
// 3
var single *Driver // 單例
var once sync.Once

// 對外暴露的公共方法
func (s *Driver) Conn() {
	fmt.Printf("conn=%s", single.conn) // do something
}

// 4
func GetDriverSingleton() *Driver {
	// 對GetDriverSingleton()方法的調(diào)用,都會執(zhí)行once.Do()方法,只不過參數(shù)func()只會被執(zhí)行一次
	// 若并發(fā)執(zhí)行once.Do(),多個協(xié)程會阻塞,因內(nèi)部是通過Mutex來控制
	once.Do(func() {
		single = new(Driver)
		single.conn = "single conn"
		time.Sleep(50 * time.Millisecond)
	})
	return single
}

單例類型定義Driver

Driver類的方法要支持跨包訪問,因此需要以大寫字母開頭。
小寫字母開頭,作用域僅限于包內(nèi)部。

類Field conn

類變量conn需要小寫字母開頭,跨包不可訪問,避免在包外被修改。

但是包內(nèi)還是有可能被修改。

once.Do(func() {})

每次調(diào)用GetDriverSingleton(),都會調(diào)用once.Do()方法,但是在once.Do()方法內(nèi)部,僅會執(zhí)行一次參數(shù)func(){},因此就保證了單例唯一初始化。

并發(fā)訪問once.Do()

不會有并發(fā)訪問問題,因once.Do()內(nèi)部通過mutex來控制。

// once.DO()
if atomic.LoadUint32(&o.done) == 0 {
	// Outlined slow-path to allow inlining of the fast-path.
	o.doSlow(f)
}

// doSlow()
func (o *Once) doSlow(f func()) {
	o.m.Lock() // 互斥鎖
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}

對外暴露方法Conn()

外部對Conn()方法的調(diào)用,最終都由單例single來實現(xiàn)。

重新new(Driver)會發(fā)生什么?

很遺憾,無法將構造函數(shù)改成private,也就是說,在包外部是可以通過new(Driver)來創(chuàng)建新的對象。

但無論是哪個對象,對公開方法Conn()的調(diào)用,最終都是由單例single來執(zhí)行的。

到此這篇關于golang實現(xiàn)單例的操作代碼的文章就介紹到這了,更多相關go單例內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go標準庫之Requests的介紹與基本使用

    Go標準庫之Requests的介紹與基本使用

    Python中的Requests庫非常強大,所以Go開發(fā)者模仿Python的Requests庫,由此誕生了Grequests庫,本文主要介紹了Requests的基本使用,有需要的可以參考下
    2024-04-04
  • Go?Gin框架路由相關bug分析

    Go?Gin框架路由相關bug分析

    這篇文章主要為大家介紹了Go?Gin框架路由相關bug分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • go語言中的return語句

    go語言中的return語句

    這篇文章主要介紹了go語言中的return語句,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你的學習有所幫助
    2022-05-05
  • 如何在golang中檢查文件是否存在

    如何在golang中檢查文件是否存在

    如果你用的是?Python,可通過?os.path.exists?這樣的標準庫函數(shù)實現(xiàn),遺憾的是,Go?標準庫沒有提供這樣直接的函數(shù),所以下面我們就來了解下如何使用GO語言能實現(xiàn)檢查文件是否存在呢
    2024-02-02
  • 詳解Go語言中ErrGroup的使用

    詳解Go語言中ErrGroup的使用

    本文主要為大家詳細介紹了Go語言中errGroup的使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-07-07
  • golang http 連接超時和傳輸超時的例子

    golang http 連接超時和傳輸超時的例子

    今天小編就為大家分享一篇golang http 連接超時和傳輸超時的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Go語言使用Timeout Context取消任務的實現(xiàn)

    Go語言使用Timeout Context取消任務的實現(xiàn)

    本文主要介紹了Go語言使用Timeout Context取消任務的實現(xiàn),包括基本的任務取消和控制HTTP客戶端請求的超時,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • golang?使用chromedp獲取頁面請求日志network

    golang?使用chromedp獲取頁面請求日志network

    這篇文章主要為大家介紹了golang?使用chromedp獲取頁面請求日志network方法實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • 詳解Go如何優(yōu)雅的對時間進行格式化

    詳解Go如何優(yōu)雅的對時間進行格式化

    這篇文章主要為大家詳細介紹了Go語言中是如何優(yōu)雅的對時間進行格式化的,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-06-06
  • 深入了解Golang中reflect反射基本原理

    深入了解Golang中reflect反射基本原理

    反射是這樣一種機制,它是可以讓我們在程序運行時(runtime)訪問、檢測和修改對象本身狀態(tài)或行為的一種能力。本文主要帶大家來看看Golang中reflect反射基本原理,需要的可以參考一下
    2023-01-01

最新評論