保证并发安全,实现如下接口typespinterface{Out(keystring,valinterface{})//存入key/val,如果该key读取的goroutine挂起,则唤醒。此方法不会阻塞,时刻都可以立即执行并返回Rd(keystring,timeouttime.Duration)interface{}//读取一个key,如果key不存在阻塞,等待key存在或者超时}
2 回答
跃然一笑
TA贡献1826条经验 获得超6个赞
可以利用channel关闭goroutine不阻塞特性来实现:下面的代码可以实现你的需求,只是没有写key被多次写入的判断逻辑。typespinterface{Out(keystring,valinterface{})//存入key/val,如果该key读取的goroutine挂起,则唤醒。此方法不会阻塞,时刻都可以立即执行并返回Rd(keystring,timeouttime.Duration)interface{}//读取一个key,如果key不存在阻塞,等待key存在或者超时}typeMapstruct{cmap[string]*entryrmx*sync.RWMutex}typeentrystruct{chchanstruct{}valueinterface{}isExistbool}func(m*Map)Out(keystring,valinterface{}){m.rmx.Lock()deferm.rmx.Unlock()ife,ok:=m.c[key];ok{e.value=vale.isExist=trueclose(e.ch)}else{e=&entry{ch:make(chanstruct{}),isExist:true,value:val}m.c[key]=eclose(e.ch)}}func(m*Map)Rd(keystring,timeouttime.Duration)interface{}{m.rmx.Lock()ife,ok:=m.c[key];ok&&e.isExist{m.rmx.Unlock()returne.value}elseif!ok{e=&entry{ch:make(chanstruct{}),isExist:false}m.c[key]=em.rmx.Unlock()fmt.Println("协程阻塞->",key)select{case<-e.ch:returne.valuecase<-time.After(timeout):fmt.Println("协程超时->",key)returnnil}}else{m.rmx.Unlock()fmt.Println("协程阻塞->",key)select{case<-e.ch:returne.valuecase<-time.After(timeout):fmt.Println("协程超时->",key)returnnil}}}
添加回答
举报
0/150
提交
取消