亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語言優(yōu)雅實(shí)現(xiàn)單例模式的多種方式

 更新時(shí)間:2025年02月06日 08:20:36   作者:燭陰  
單例模式(Singleton Pattern)是一種設(shè)計(jì)模式,旨在保證一個(gè)類只有一個(gè)實(shí)例,并且提供全局訪問點(diǎn),單例模式通常用于需要限制某個(gè)對(duì)象的實(shí)例數(shù)量為一個(gè)的場(chǎng)景,本文給大家介紹了Go語言實(shí)現(xiàn)單例模式的多種方式,需要的朋友可以參考下

單例模式的基本定義

單例模式(Singleton Pattern)是一種設(shè)計(jì)模式,旨在保證一個(gè)類只有一個(gè)實(shí)例,并且提供全局訪問點(diǎn)。單例模式通常用于需要限制某個(gè)對(duì)象的實(shí)例數(shù)量為一個(gè)的場(chǎng)景,比如數(shù)據(jù)庫(kù)連接池、日志管理器、配置管理器等。

Go語言單例模式的實(shí)現(xiàn)

1. 線程安全的懶漢式單例

懶漢式的實(shí)現(xiàn)會(huì)延遲實(shí)例的創(chuàng)建,直到第一次調(diào)用時(shí)才會(huì)實(shí)例化對(duì)象。為了保證并發(fā)情況下的安全性,我們需要使用 sync.Once 來確保實(shí)例只會(huì)創(chuàng)建一次。

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

// Singleton 類型
type Singleton struct {
}

var instance *Singleton
var once sync.Once

// GetInstance 提供全局唯一的實(shí)例
func GetInstance() *Singleton {

	once.Do(func() {
		instance = &Singleton{}
	})
	return instance
}

func main() {
	// 獲取單例實(shí)例
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(index int) {
			defer wg.Done()
			s1 := GetInstance()
			fmt.Printf("index %d, memery address: %p\n", index, s1)
		}(i)

	}
	wg.Wait()
}

結(jié)果

index 0, memery address: 0x56c480
index 5, memery address: 0x56c480
index 4, memery address: 0x56c480
index 2, memery address: 0x56c480
index 7, memery address: 0x56c480
index 9, memery address: 0x56c480
index 6, memery address: 0x56c480
index 8, memery address: 0x56c480
index 3, memery address: 0x56c480
index 1, memery address: 0x56c480

解析:

  • sync.Once:Go標(biāo)準(zhǔn)庫(kù)提供的一個(gè)同步原語,確保某個(gè)函數(shù)只會(huì)被調(diào)用一次。它在并發(fā)情況下保證了線程安全。
  • once.Do:此方法確保傳入的函數(shù)只執(zhí)行一次,適用于懶加載單例實(shí)例。

2. 雙重檢查鎖定(DCL)

雙重檢查鎖定是一種優(yōu)化方式,它通過在兩次檢查實(shí)例時(shí),減少了加鎖的開銷,提高了性能。

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

// Singleton 類型
type Singleton struct {
}

var instance *Singleton
var lock sync.Mutex

func GetInstance() *Singleton {
	if instance == nil {
		lock.Lock()
		defer lock.Unlock()
		if instance == nil {
			instance = &Singleton{}
		}
	}
	return instance
}

func main() {
	// 獲取單例實(shí)例
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(index int) {
			defer wg.Done()
			s1 := GetInstance()
			fmt.Printf("index %d, memery address: %p\n", index, s1)
		}(i)

	}
	wg.Wait()
}

解析:

  • 雙重檢查:第一次檢查實(shí)例是否為 nil,如果是,則加鎖。然后再次檢查實(shí)例是否為 nil,如果是則創(chuàng)建實(shí)例。
  • 鎖的優(yōu)化:只有在實(shí)例尚未創(chuàng)建時(shí)才會(huì)加鎖,避免了每次獲取實(shí)例時(shí)都需要加鎖的性能損耗。

3. 原子操作法

Go 語言的 sync/atomic 包提供了原子操作,我們可以利用它來確保單例的線程安全。

package main

import (
	"fmt"
	"sync"
	"sync/atomic"
	"unsafe"
)

var wg sync.WaitGroup

type Singleton struct {
}

var instance unsafe.Pointer

func GetInstance() *Singleton {
	// 使用原子操作獲取實(shí)例
	if atomic.LoadPointer(&instance) == nil {
		newInstance := &Singleton{}
		atomic.StorePointer(&instance, unsafe.Pointer(newInstance))
	}
	return (*Singleton)(atomic.LoadPointer(&instance))
}

func main() {
	// 獲取單例實(shí)例
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(index int) {
			defer wg.Done()
			s1 := GetInstance()
			fmt.Printf("index %d, memery address: %p\n", index, s1)
		}(i)

	}
	wg.Wait()
}

解析:

  • unsafe.Pointer:在Go中,unsafe.Pointer 可以用來繞過類型系統(tǒng),直接處理內(nèi)存地址。通過原子操作確保實(shí)例賦值的安全性。
  • atomic.LoadPointeratomic.StorePointer:原子加載和存儲(chǔ)指針,確保操作的線程安全性。

總結(jié)

在Go語言中實(shí)現(xiàn)單例模式有多種方式,最常見的是使用 sync.Once、雙重檢查鎖定(DCL)和原子操作法。每種方法有其優(yōu)缺點(diǎn),選擇合適的方式可以幫助你在保證線程安全的前提下優(yōu)化性能。

到此這篇關(guān)于Go語言優(yōu)雅實(shí)現(xiàn)單例模式的多種方式的文章就介紹到這了,更多相關(guān)Go實(shí)現(xiàn)單例模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 讓go程序以后臺(tái)進(jìn)程或daemon方式運(yùn)行方法探究

    讓go程序以后臺(tái)進(jìn)程或daemon方式運(yùn)行方法探究

    本文探討了如何通過Go代碼實(shí)現(xiàn)在后臺(tái)運(yùn)行的程序,最近我用Go語言開發(fā)了一個(gè)WebSocket服務(wù),我希望它能在后臺(tái)運(yùn)行,并在異常退出時(shí)自動(dòng)重新啟動(dòng),我的整體思路是將程序轉(zhuǎn)為后臺(tái)進(jìn)程,也就是守護(hù)進(jìn)程(daemon)
    2024-01-01
  • Go語言文件操作的方法

    Go語言文件操作的方法

    這篇文章主要介紹了Go語言文件操作的方法,涉及文件的讀寫及關(guān)閉等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • 基于go手動(dòng)寫個(gè)轉(zhuǎn)發(fā)代理服務(wù)的代碼實(shí)現(xiàn)

    基于go手動(dòng)寫個(gè)轉(zhuǎn)發(fā)代理服務(wù)的代碼實(shí)現(xiàn)

    這篇文章主要介紹了基于go手動(dòng)寫個(gè)轉(zhuǎn)發(fā)代理服務(wù)的代碼實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 一文搞懂Go語言標(biāo)準(zhǔn)庫(kù)strconv

    一文搞懂Go語言標(biāo)準(zhǔn)庫(kù)strconv

    strconv包實(shí)現(xiàn)了基本數(shù)據(jù)類型和其字符串表示的相互轉(zhuǎn)換,本文主要介紹Go語言標(biāo)準(zhǔn)庫(kù)strconv,想要學(xué)習(xí)strconv標(biāo)準(zhǔn)庫(kù)的可以了解一下
    2023-04-04
  • VSCode1.4 搭建Golang的開發(fā)調(diào)試環(huán)境(遇到很多問題)

    VSCode1.4 搭建Golang的開發(fā)調(diào)試環(huán)境(遇到很多問題)

    這篇文章主要介紹了VSCode1.4 搭建Golang的開發(fā)調(diào)試環(huán)境(遇到很多問題),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 一文教你如何快速學(xué)會(huì)Go的struct數(shù)據(jù)類型

    一文教你如何快速學(xué)會(huì)Go的struct數(shù)據(jù)類型

    結(jié)構(gòu)是表示字段集合的用戶定義類型。它可以用于將數(shù)據(jù)分組為單個(gè)單元而不是將每個(gè)數(shù)據(jù)作為單獨(dú)的值的地方。本文就來和大家聊聊Go中struct數(shù)據(jù)類型的使用,需要的可以參考一下
    2023-03-03
  • Golang實(shí)現(xiàn)IO操作

    Golang實(shí)現(xiàn)IO操作

    本文主要介紹了Golang實(shí)現(xiàn)IO操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Go語言刪除文本文件中的指定行操作代碼

    Go語言刪除文本文件中的指定行操作代碼

    假設(shè)現(xiàn)在有一個(gè)文本文件,我們需要?jiǎng)h除文件中亂碼的行。我們可以使用go的os庫(kù)來處理文件,遍歷整個(gè)文件然后將除過亂碼的行寫入一個(gè)新文件,以此來實(shí)現(xiàn)我們的需求,這篇文章主要介紹了Go語言刪除文本文件中的指定行,需要的朋友可以參考下
    2023-12-12
  • Go語言調(diào)用ffmpeg-api實(shí)現(xiàn)音頻重采樣

    Go語言調(diào)用ffmpeg-api實(shí)現(xiàn)音頻重采樣

    最近對(duì)golang處理音視頻很感興趣,對(duì)golang音視頻常用庫(kù)goav進(jìn)行了一番研究。自己寫了一個(gè)wav轉(zhuǎn)采樣率的功能。給大家分享一下,中間遇到了不少坑,解決的過程中還是蠻有意思的,希望大家能喜歡
    2022-12-12
  • Golang 之協(xié)程的用法講解

    Golang 之協(xié)程的用法講解

    這篇文章主要介紹了Golang 之協(xié)程的用法講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評(píng)論