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

Go單例模式與Once源碼實現(xiàn)

 更新時間:2022年12月08日 11:13:53   作者:如雨隨行2020  
這篇文章主要介紹了Go單例模式與Once源碼實現(xiàn),本文結(jié)合示例代碼給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

單例實現(xiàn)

type singleton struct{}

var (
	instance    *singleton
	initialized uint32
	mu          sync.Mutex
)

func Instance() *singleton {
	if atomic.LoadUint32(&initialized) == 1 {
		return instance
	}

	mu.Lock()
	defer mu.Unlock()

	if instance == nil {
		defer atomic.StoreUint32(&initialized, 1)
		instance = &singleton{}
	}
	return instance
}

其中通用的代碼提取出來,就成了標(biāo)準(zhǔn)庫中sync.Once的實現(xiàn):

type Once struct {
	done uint32
	m    sync.Mutex
}

func (o *Once) Do(f func()) {
	if atomic.LoadUint32(&o.done) == 0 {

		o.m.Lock()
		defer o.m.Unlock()

		if o.done == 0 {
			defer atomic.StoreUint32(&o.done, 1)
			f()
		}
	}
}

于是,使用sync.Once重新實現(xiàn)單例模式

var (
	instance2 *singleton
	once sync.Once
)

func Instance2() *singleton {
	once.Do(func() {
		instance2 = &singleton{}
	})
	return instance2
}

sync.Once源碼分析

1. lock并不會同步值

在lock和unlock之間修改值,并不會保證對其他協(xié)程是可見的,除非使用相同的Mutex加鎖,想要同步值必須使用atomic;

lock可以通過串行化,使得兩個協(xié)程的操作存在happen-before關(guān)系,從而是的操作可見

happen-before原則定義如下:

如果一個操作happens-before(之前發(fā)生)另一個操作,那么第一個操作的執(zhí)行結(jié)果將對第二個操作可見,而且第一個操作的執(zhí)行順序排在第二個操作之前。

兩個操作之間存在happens-before關(guān)系,并不意味著一定要按照happens-before原則制定的順序來執(zhí)行。如果重排序之后的執(zhí)行結(jié)果與按照happens-before關(guān)系來執(zhí)行的結(jié)果一致,那么這種重排序并不非法。

2. Do執(zhí)行一次

當(dāng)?shù)谝淮螆?zhí)行完Do之后,done設(shè)置成1,后面執(zhí)行Do會直接跳過

3. Once執(zhí)行Do后不準(zhǔn)copy

A Once must not be copied after first use.

sync.Once執(zhí)行完Dodone已經(jīng)設(shè)置成1了,copy出來的once執(zhí)行Do會直接跳過

4. Do并發(fā)時阻塞

當(dāng)兩個或者多個協(xié)程同時調(diào)用Do時,先調(diào)用的協(xié)程執(zhí)行,后面的協(xié)程會阻塞;

解釋:以單例使用once的實現(xiàn)說明,兩個協(xié)程同時調(diào)用Instance2(),先調(diào)用的協(xié)程執(zhí)行創(chuàng)建并拿到返回值,后調(diào)用的阻塞,

? 等到先調(diào)用的完成后再拿到返回值;

意義:這樣的好處是防止后調(diào)用的協(xié)程拿到的是nil

源碼說明:上面第二段代碼13行使用defer,要等f()結(jié)束才會把done設(shè)置成1;其他協(xié)程并發(fā)調(diào)用Do時,done==0,

? 然后請求m.Lock()形成阻塞

5. Do遞歸死鎖

如果Do中的方法調(diào)用當(dāng)前once的Do會造成死鎖,原因參考上面一點(sync.Mutex.Lock()時不可重入鎖)

參考

  • 《Go語言高級編程》
  • Go1.16源碼

相關(guān)文章

  • go從指定的URL下載圖片并保存到本地的代碼實現(xiàn)

    go從指定的URL下載圖片并保存到本地的代碼實現(xiàn)

    這段代碼定義了一個名為 downloadImage 的函數(shù),其目的是從指定的URL下載圖片并保存到本地文件系統(tǒng),本文是對代碼功能的詳細(xì)描述,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-08-08
  • golang?chan傳遞數(shù)據(jù)的性能開銷詳解

    golang?chan傳遞數(shù)據(jù)的性能開銷詳解

    這篇文章主要為大家詳細(xì)介紹了Golang中chan在接收和發(fā)送數(shù)據(jù)時因為“復(fù)制”而產(chǎn)生的開銷,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2024-01-01
  • Golang原生rpc(rpc服務(wù)端源碼解讀)

    Golang原生rpc(rpc服務(wù)端源碼解讀)

    本文主要介紹了Golang原生rpc(rpc服務(wù)端源碼解讀),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 利用Go語言快速實現(xiàn)一個極簡任務(wù)調(diào)度系統(tǒng)

    利用Go語言快速實現(xiàn)一個極簡任務(wù)調(diào)度系統(tǒng)

    任務(wù)調(diào)度(Task Scheduling)是很多軟件系統(tǒng)中的重要組成部分,字面上的意思是按照一定要求分配運行一些通常時間較長的腳本或程序。本文將利用Go語言快速實現(xiàn)一個極簡任務(wù)調(diào)度系統(tǒng),感興趣的可以了解一下
    2022-10-10
  • golang?gorm的Callbacks事務(wù)回滾對象操作示例

    golang?gorm的Callbacks事務(wù)回滾對象操作示例

    這篇文章主要為大家介紹了golang?gorm的Callbacks事務(wù)回滾對象操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Go語言中匿名嵌套和類型嵌套的區(qū)別解析

    Go語言中匿名嵌套和類型嵌套的區(qū)別解析

    在Go語言中,匿名嵌套結(jié)構(gòu)體和與類型同名的嵌套結(jié)構(gòu)體不是完全等價的,它們有一些重要的區(qū)別,這篇文章主要介紹了Go語言中匿名嵌套和類型嵌套的區(qū)別,需要的朋友可以參考下
    2023-09-09
  • go實現(xiàn)redigo的簡單操作

    go實現(xiàn)redigo的簡單操作

    golang操作redis主要有兩個庫,go-redis和redigo,今天我們就一起來介紹一下redigo的實現(xiàn)方法,需要的朋友可以參考下
    2018-07-07
  • 淺析Gin框架中路由參數(shù)的使用

    淺析Gin框架中路由參數(shù)的使用

    這篇文章主要為大家介紹了路由參數(shù)的基本語法,以及路由匹配和路由參數(shù)值提取等相關(guān)內(nèi)容,以幫助讀者更好地對Gin?框架中路由參數(shù)進(jìn)行使用,需要的可以參考下
    2023-08-08
  • Go語言之init函數(shù)

    Go語言之init函數(shù)

    Go語言有一個特殊的函數(shù)init,先于main函數(shù)執(zhí)行,實現(xiàn)包級別的一些初始化操作。這篇文章介紹了Go中的Init函數(shù),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Golang限流庫與漏桶和令牌桶的使用介紹

    Golang限流庫與漏桶和令牌桶的使用介紹

    這篇文章主要介紹了golang限流庫以及漏桶與令牌桶的實現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-03-03

最新評論