golang实现并发安全map

Posted by kzdgt on Tuesday, May 16, 2023

请用golang的map进行封装,不加锁,不用sync.map,实现一个并发安全的、高性能的map

好的,我可以为您实现一个类似concurrent-map的并发安全的map,基于channel和goroutine实现,同时也是高性能的。它有三个方法:添加、获取和删除。具体实现代码如下:

type ConcurrentMap struct {
	data     map[any]any
	addCh    chan mapEntry
	getCh    chan any
	delCh    chan any
	resultCh chan any
}

type mapEntry struct {
	key, value any
}

func NewConcurrentMap() *ConcurrentMap {
	cmap := &ConcurrentMap{
		data:     make(map[any]any),
		addCh:    make(chan mapEntry),
		getCh:    make(chan any),
		delCh:    make(chan any),
		resultCh: make(chan any),
	}

	go cmap.run()

	return cmap
}

func (cmap *ConcurrentMap) Get(key any) (any, bool) {
	cmap.getCh <- key
	result := <-cmap.resultCh
	if result == nil {
		return result, false
	}
	return result, true
}

func (cmap *ConcurrentMap) Set(key, value any) {
	cmap.addCh <- mapEntry{key, value}
}

func (cmap *ConcurrentMap) Delete(key any) {
	cmap.delCh <- key
}

func (cmap *ConcurrentMap) run() {
	for {
		select {
		case entry := <-cmap.addCh:
			cmap.data[entry.key] = entry.value
		case key := <-cmap.getCh:
			r, ok := cmap.data[key]
			if !ok {
				r = nil
			}
			cmap.resultCh <- r
		case key := <-cmap.delCh:
			delete(cmap.data, key)
		}
	}
}

使用方法:

cmap := NewConcurrentMap()
cmap.Set("foo", "bar")
val := cmap.Get("foo")
cmap.Delete("foo")

这样的实现不需要显式加锁,因为channel可以通过堵塞阻止并发数据访问导致的数据竞争。 由于数据访问被串行化,因此性能也非常高,并且在并发环境中是安全的。

「真诚赞赏,手留余香」

kzdgt Blog

真诚赞赏,手留余香

使用微信扫描二维码完成支付