3 回答

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超4個(gè)贊
使用單程套餐。為該組聲明一個(gè)包級(jí)變量:
var?g?singleflight.Group
使用以下代碼獲取值:
v, err, _ := g.Do(key, func() (interface{}, error) {
? ? if !hasCachedValue(key) {
? ? ? ? buildCacheValue(key)
? ? }
? ? return cachedValue(key), nil
})
if err != nil {
? ? // handle error
}
x := v.(valueType) // assert to type returned by cachedValue
// do something with x

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個(gè)贊
這是一個(gè)簡(jiǎn)單的代碼,可以完成您想要的操作。我測(cè)試了它,它工作沒有問題。Go 競(jìng)爭(zhēng)條件檢查器沒有檢測(cè)到任何問題。
type Cache struct {
mtx sync.RWMutex
m map[KeyType]*CacheValue
}
type CacheValue struct {
val *ValueType
mtx sync.Mutex
}
func NewCache() *Cache {
return &Cache{m: make(map[KeyType]*CacheValue)}
}
func (c *Cache) Get(key KeyType) *ValueType {
c.mtx.RLock()
v := c.m[key]
c.mtx.RUnlock()
if v != nil {
v.mtx.Lock()
x := v.val
v.mtx.Unlock()
if x != nil {
return x
}
}
if v == nil {
c.mtx.Lock()
v = c.m[key]
if v == nil {
v = &CacheValue{}
c.m[key] = v
}
c.mtx.Unlock()
}
v.mtx.Lock()
if v.val == nil {
v.val = buildValue(key)
}
v.mtx.Unlock()
return v.val
}

TA貢獻(xiàn)1900條經(jīng)驗(yàn) 獲得超5個(gè)贊
受到經(jīng)常用于描述通道的乒乓球示例的啟發(fā),我們嘗試了僅通道方法。球保存有關(guān)正在生成的密鑰的狀態(tài),并且球在共享通道的請(qǐng)求之間傳遞:
import "time"
var table = make(chan map[string]chan bool)
func keeper() {
for {
ball := <- table
table <- ball
}
}
func getResource(key string) {
// Take ball from table
ball := <- table
if wait, ok := ball[key]; ok{
println("Somebody else working on " + key + ", waiting")
table <- ball
<- wait
} else {
println("I will build " + key)
ball[key] = make(chan bool)
// Throw away ball
table <- ball
// Building value
time.Sleep(time.Millisecond * 10)
println("I built value for " + key + "!")
// Clean up ball
ball = <- table
close(ball[key])
delete(ball, key)
table <- ball
}
println("Now value for " + key + " has been built")
}
func main(){
go keeper()
ball := make(map[string]chan bool)
table <- ball
key := "key"
go getResource(key)
go getResource(key)
go getResource(key)
time.Sleep(time.Second)
}
- 3 回答
- 0 關(guān)注
- 192 瀏覽
添加回答
舉報(bào)