package jconcurrency import ( "sync" ) //HashMap对象,局限安全操作,对外暴露了锁和数据,在自行遍历如果再加锁就会死锁! type JyMap struct { Lock sync.RWMutex Data map[any]any } func NewJM() *JyMap { return &JyMap{Data: map[any]any{}} } //设置 func (jm *JyMap) Set(k, v any) { jm.Lock.Lock() jm.Data[k] = v jm.Lock.Unlock() } //获取 func (jm *JyMap) Get(k any) (v any) { jm.Lock.RLock() defer jm.Lock.RUnlock() return jm.Data[k] } //获取并删除 func (jm *JyMap) GetAndDel(k any) (v any) { jm.Lock.Lock() defer jm.Lock.Unlock() v = jm.Data[k] delete(jm.Data, k) return } //仅删除 func (jm *JyMap) Del(k any) { jm.Lock.Lock() defer jm.Lock.Unlock() delete(jm.Data, k) return } //如果不存在则设置 func (jm *JyMap) SetIfNoExists(k, v any) { jm.Lock.Lock() defer jm.Lock.Unlock() if jm.Data[k] == nil { jm.Data[k] = v } } //map中是否存在 func (jm *JyMap) Has(k any) bool { jm.Lock.RLock() defer jm.Lock.RUnlock() return jm.Data[k] != nil } //长度 func (jm *JyMap) Len() int { jm.Lock.RLock() defer jm.Lock.RUnlock() return len(jm.Data) } //如果不使用此方法遍历,再调用自身的方法加锁,就会死锁 //目前没有找到好的解决办法,只有自己控制好,特别是遍历的时候同时修改map func (jm *JyMap) Iter(fn func(k, v any) bool) { jm.Lock.RLock() ch := make(chan []any, len(jm.Data)) go func() { L1: for { select { case arr, ok := <-ch: if !fn(arr[0], arr[1]) || !ok { _ = ch break L1 } } } }() for k, v := range jm.Data { ch <- []any{k, v} } close(ch) jm.Lock.RUnlock() }