go笔记--协程安全map的四种方法

go笔记–go协程安全map的四种方法


读写锁

这个应该是最简单的方法,读取的时候加读锁,修改的时候加写锁。

type LockMap struct {
	m map[interface{}]interface{}
	sync.RWMutex
}

func (lm *LockMap) Get(key interface{}) (value interface{}, ok bool) {
	lm.RLock()
	defer lm.RUnlock()
	value, ok = lm.m[key]
	return
}

func (lm *LockMap) Put(key interface{}, value interface{}) {
	lm.Lock()
	defer lm.Unlock()
	lm.m[key] = value
}

func (lm *LockMap) Del(key interface{}) {
	lm.Lock()
	defer lm.Unlock()
	delete(lm.m, key)
}

sync.map

同时sync.Map是不需要初始化的。

var smap sync.Map

func Set (k,v interface{}){
    smap.Store(k,v)
}

func Get (k interface{}) interface{}{
    v ,exit := smap.Load(k)
    if exit {
        return v
    }
    return nil
}

func Del(key interface{}){
    smap.Delete(key)
}

func MapRange (funcs func(key, value interface{}) bool) {
    smap.Range(funcs)
}

atomic.Value

在kratos 里面看到的一种协程安全map,利用了atomic.Value来封装的。

package paladin

import (
	"strings"
	"sync/atomic"
)

// KeyNamed key naming to lower case.
func KeyNamed(key string) string {
	return strings.ToLower(key)
}

// Map is config map, key(filename) -> value(file).
type Map struct {
	values atomic.Value
}

// Store sets the value of the Value to values map.
func (m *Map) Store(values map[string]*Value) {
	dst := make(map[string]*Value, len(values))
	for k, v := range values {
		dst[KeyNamed(k)] = v
	}
	m.values.Store(dst)
}

// Load returns the value set by the most recent Store.
func (m *Map) Load() map[string]*Value {
	src := m.values.Load().(map[string]*Value)
	dst := make(map[string]*Value, len(src))
	for k, v := range src {
		dst[k] = v
	}
	return dst
}

// Exist check if values map exist a key.
func (m *Map) Exist(key string) bool {
	_, ok := m.Load()[KeyNamed(key)]
	return ok
}

// Get return get value by key.
func (m *Map) Get(key string) *Value {
	v, ok := m.Load()[KeyNamed(key)]
	if ok {
		return v
	}
	return &Value{}
}

// Keys return map keys.
func (m *Map) Keys() []string {
	values := m.Load()
	keys := make([]string, 0, len(values))
	for key := range values {
		keys = append(keys, key)
	}
	return keys
}

chan

最后一种方法当然就是管道啦,select:case 万精油的方法嘛, 这里就不放例程了。

发布了123 篇原创文章 · 获赞 156 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/qq_17308321/article/details/103713275