最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言如何實(shí)現(xiàn)線程安全的Map

 更新時(shí)間:2024年11月26日 09:09:30   作者:熬了夜的程序員  
Go語(yǔ)言內(nèi)置的map雖然高效,但并不是線程安全的,若在多線程環(huán)境中直接操作map,可能會(huì)引發(fā)并發(fā)寫入的錯(cuò)誤,下面我們就來(lái)看看如何實(shí)現(xiàn)線程安全的Map吧

在并發(fā)編程中,數(shù)據(jù)共享和訪問(wèn)是一個(gè)重要的主題。Go語(yǔ)言內(nèi)置的map雖然高效,但并不是線程安全的。若在多線程環(huán)境中直接操作map,可能會(huì)引發(fā)并發(fā)寫入的錯(cuò)誤(fatal error: concurrent map writes)。因此,在需要并發(fā)訪問(wèn)map時(shí),必須采取措施確保線程安全。

本文將介紹如何使用Go語(yǔ)言的泛型和sync.RWMutex實(shí)現(xiàn)一個(gè)線程安全的Map,同時(shí)支持常見的操作,例如增刪改查、遍歷和轉(zhuǎn)化為普通的Map。

1. 為什么需要線程安全的Map

Go語(yǔ)言內(nèi)置的map在多線程環(huán)境中并不安全。例如,以下代碼可能引發(fā)崩潰:

package main

import (
	"fmt"
	"sync"
)

func main() {
	m := make(map[int]int)
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			m[i] = i
		}(i)
	}

	wg.Wait()
	fmt.Println(m)
}

運(yùn)行上述代碼可能會(huì)報(bào)錯(cuò):fatal error: concurrent map writes。這是因?yàn)閙ap的寫操作沒(méi)有加鎖,在多線程中引發(fā)了競(jìng)態(tài)條件。

2. 如何實(shí)現(xiàn)線程安全的Map

Go標(biāo)準(zhǔn)庫(kù)提供了sync.Map,它是線程安全的。但它的API相對(duì)簡(jiǎn)單,缺乏泛型支持且性能在某些場(chǎng)景下并不理想。因此,我們可以基于sync.RWMutex和泛型封裝一個(gè)自定義的線程安全Map。

2.1 基本實(shí)現(xiàn)

以下是線程安全SyncMap的完整實(shí)現(xiàn):

package syncmap

import (
	"sync"
)

// SyncMap 定義了一個(gè)線程安全的泛型Map
type SyncMap[K comparable, V any] struct {
	mu sync.RWMutex
	m  map[K]V
}

// NewSyncMap 創(chuàng)建一個(gè)新的線程安全的SyncMap
func NewSyncMap[K comparable, V any]() *SyncMap[K, V] {
	return &SyncMap[K, V]{
		m: make(map[K]V),
	}
}

// Load 獲取指定key的值,如果存在返回值和true,否則返回零值和false
func (s *SyncMap[K, V]) Load(key K) (V, bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	val, ok := s.m[key]
	return val, ok
}

// Store 設(shè)置指定key的值,如果key已存在會(huì)覆蓋舊值
func (s *SyncMap[K, V]) Store(key K, value V) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.m[key] = value
}

// Has returns true if the key exists in the map.
func (s *SyncMap[K, V]) Has(key K) bool {
	s.mu.RLock()
	defer s.mu.RUnlock()

	_, ok := s.m[key]
	return ok
}


// Delete 刪除指定key的值
func (s *SyncMap[K, V]) Delete(key K) {
	s.mu.Lock()
	defer s.mu.Unlock()
	delete(s.m, key)
}

// Range 遍歷所有的鍵值對(duì),callback函數(shù)返回false時(shí)停止遍歷
func (s *SyncMap[K, V]) Range(callback func(key K, value V) bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	for k, v := range s.m {
		if !callback(k, v) {
			break
		}
	}
}

// Len returns the length of the map.
func (s *SyncMap[K, V]) Len() int {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return len(s.m)
}

// ToMap 轉(zhuǎn)化為普通的map,返回一個(gè)線程安全的副本
func (s *SyncMap[K, V]) ToMap() map[K]V {
	s.mu.RLock()
	defer s.mu.RUnlock()

	copyMap := make(map[K]V, len(s.m))
	for k, v := range s.m {
		copyMap[k] = v
	}
	return copyMap
}

2.2 關(guān)鍵功能說(shuō)明

線程安全:

  • 讀操作使用sync.RWMutex的RLock,允許并發(fā)讀取。
  • 寫操作使用sync.RWMutex的Lock,確保寫操作互斥。

支持泛型:

通過(guò)K和V泛型參數(shù)支持任意鍵值類型,其中K必須是可比較的。

基本操作:

  • Load:獲取值。
  • Store:設(shè)置值。
  • Has:判斷鍵是否存在。
  • Delete:刪除鍵值對(duì)。
  • Range:遍歷所有鍵值對(duì)。
  • Len:獲取map的長(zhǎng)度。
  • ToMap:轉(zhuǎn)化為普通map。

3. 使用示例

以下代碼演示了SyncMap的基本用法:

package main

import (
	"fmt"
	"syncmap"
)

func main() {
	// 創(chuàng)建一個(gè)線程安全的Map
	m := syncmap.NewSyncMap[string, int]()

	// 添加值
	m.Store("one", 1)
	m.Store("two", 2)

	// 獲取值
	if val, ok := m.Load("one"); ok {
		fmt.Println("Key 'one':", val)
	} else {
		fmt.Println("Key 'one' not found")
	}

	// 刪除值
	m.Delete("one")

	// 遍歷所有鍵值對(duì)
	m.Range(func(key string, value int) bool {
		fmt.Printf("Key: %s, Value: %d
", key, value)
		return true
	})

	// 轉(zhuǎn)化為普通map
	ordinaryMap := m.ToMap()
	fmt.Println("Ordinary map:", ordinaryMap)
}

運(yùn)行結(jié)果:

Key 'one': 1
Key: two, Value: 2
Ordinary map: map[two:2]

4. 總結(jié)

自定義線程安全的SyncMap具備以下優(yōu)點(diǎn):

  • 泛型支持:靈活適配不同類型的鍵值。
  • 線程安全:支持高并發(fā)場(chǎng)景的安全訪問(wèn)。
  • 可擴(kuò)展性:易于添加更多功能,如合并操作、條件更新等。

通過(guò)本文的實(shí)現(xiàn)與示例,希望您能更好地理解和應(yīng)用線程安全Map,構(gòu)建健壯的并發(fā)應(yīng)用。

到此這篇關(guān)于Go語(yǔ)言如何實(shí)現(xiàn)線程安全的Map的文章就介紹到這了,更多相關(guān)Go線程安全Map內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入Golang中的sync.Pool詳解

    深入Golang中的sync.Pool詳解

    這篇文章主要介紹了深入Golang中的sync.Pool詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • go mod tidy加載模塊超時(shí)的問(wèn)題及解決

    go mod tidy加載模塊超時(shí)的問(wèn)題及解決

    go mod tidy加載模塊超時(shí)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 淺談golang結(jié)構(gòu)體偷懶初始化

    淺談golang結(jié)構(gòu)體偷懶初始化

    這篇文章主要介紹了淺談golang結(jié)構(gòu)體偷懶初始化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Golang實(shí)現(xiàn)AES對(duì)稱加密算法實(shí)例詳解

    Golang實(shí)現(xiàn)AES對(duì)稱加密算法實(shí)例詳解

    所謂對(duì)稱加密是指在加密和解碼時(shí)使用同一密鑰的加密方式,下面這篇文章主要給大家介紹了關(guān)于Golang實(shí)現(xiàn)AES對(duì)稱加密算法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn)

    Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn)

    RSA 是最常用的非對(duì)稱加密算法,本文主要介紹了Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • Go 類型轉(zhuǎn)換工具包strconv包的用法

    Go 類型轉(zhuǎn)換工具包strconv包的用法

    Go 語(yǔ)言的?strconv?包提供了用于基本數(shù)據(jù)類型之間轉(zhuǎn)換的函數(shù),本文主要介紹了Go 類型轉(zhuǎn)換工具包strconv包的用法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • 詳解Golang開啟http服務(wù)的三種方式

    詳解Golang開啟http服務(wù)的三種方式

    這篇文章主要介紹了詳解Golang開啟http服務(wù)的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 詳解Golang中哪些類型可以作為map的key

    詳解Golang中哪些類型可以作為map的key

    在 Go 語(yǔ)言中,map 是一種內(nèi)置的關(guān)聯(lián)數(shù)據(jù)結(jié)構(gòu)類型,由一組無(wú)序的鍵值對(duì)組成,每個(gè)鍵都是唯一的,并與一個(gè)對(duì)應(yīng)的值相關(guān)聯(lián),本文將詳細(xì)介紹哪些類型的變量可以作為 map 的鍵,并通過(guò)實(shí)例進(jìn)行說(shuō)明,感興趣的朋友可以參考下
    2024-01-01
  • GoLang編程必備:GoFrame?GoLand插件介紹

    GoLang編程必備:GoFrame?GoLand插件介紹

    掌握GoLang編程必備工具,我們來(lái)深入了解GoFrame?GoLand插件,這個(gè)小巧但強(qiáng)大的插件將極大提升你的開發(fā)效率,讓代碼流暢如行云流水,一起跟隨本指南,解鎖更智能的編程之旅!
    2023-12-12
  • Go語(yǔ)言中的Base64編碼原理介紹以及使用

    Go語(yǔ)言中的Base64編碼原理介紹以及使用

    Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一,可用于在HTTP環(huán)境下傳遞較長(zhǎng)的標(biāo)識(shí)信息,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中的Base64編碼原理介紹以及使用的相關(guān)資料,需要的朋友可以參考下
    2022-01-01

最新評(píng)論

松原市| 峨眉山市| 类乌齐县| 凤凰县| 广灵县| 涟水县| 叙永县| 岳普湖县| 永胜县| 临桂县| 赤城县| 云南省| 防城港市| 芦山县| 华坪县| 灵山县| 肃南| 什邡市| 华坪县| 北安市| 礼泉县| 呼伦贝尔市| 大同市| 宣化县| 陵川县| 井冈山市| 临西县| 阿合奇县| 新野县| 阆中市| 屏边| 特克斯县| 共和县| 扶风县| 东丽区| 白朗县| 平凉市| 大安市| 自贡市| 涞源县| 红安县|