Golang 使用装饰器模式实现并发安全Map容器

47 阅读1分钟

Golang 使用装饰器模式实现并发安全Map容器

项目地址:github.com/fengyuan-li… (学习使用,请谨慎在生产项目使用)

其他更加完善的项目:github.com/emirpasic/g… (这个库数据结构比较完善,但是没有泛型)

在golang中map通过关键字给出,是线程不安全的。

这里笔者包装了一层map,并定义了IMap的接口,可以选择不同的实现,例如LinkedHashMapTreeMap等等

这样我们就可以通过统一的方式,对所有实现IMap的Map进行装饰,让其变成线程安全的

 // SynchronizedMap is a thread-safe map
 type SynchronizedMap[K comparable, V any] struct {
     m  IMap[K, V] // raw map
     mu *sync.RWMutex
 }
 ​
 // NewSynchronizedMap creates a new SynchronizedMap
 func NewSynchronizedMap[K comparable, V any](rawMap IMap[K, V]) IMap[K, V] {
     return &SynchronizedMap[K, V]{
         m:  rawMap,
         mu: new(sync.RWMutex),
     }
 }
 ​
 // 下面是在方法中加读写锁进行实现,例如put方法
 // Put adds a key-value pair to the map
 func (s *SynchronizedMap[K, V]) Put(k K, v V) {
     s.mu.Lock()
     defer s.mu.Unlock()
     s.m.Put(k, v)
 }
 ​

使用也非常简单

 // 直接使用线程安全的map
 syncMap := NewConcurrentHashMap[string, int]()
 ​
 // 包装需要线程安全的map
 ​
 // NewConcurrentLinkedHashMap creates a new thread-safe linked hash map.
 // It returns an implementation of the IMap interface using a SynchronizedMap that wraps a NewLinkedHashMap.
 func NewConcurrentLinkedHashMap[K comparable, V any]() IMap[K, V] {
     return NewSynchronizedMap[K, V](NewLinkedHashMap[K, V]())
 }

需要声明的是,笔者的库主要是学习使用,读者可以用同样的思路包装github.com/emirpasic/g…里面的map,使其变的线程安全