代码原来的地址是:https://github.com/golang/groupcache/blob/master/singleflight/singleflight_test.go
片段如下:
<pre>
func TestDoDupSuppress(t *testing.T) {
var g Group
c:=make(chan string)
var calls int32
fn:= func() (interface{},error){
atomic.AddInt32(&calls,1)
return <-c,nil
}
const n=10
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
v,err:=g.Do("key",fn)
if err != nil {
t.Errorf("Do error: %v",err)
}
if v.(string) != "bar" {
t.Errorf("got %q; want %q",v,"bar")
}
wg.Done()
}()
}
//不sleep会卡住,执行不下去,为什么呢
// 原来的注释是 “ let goroutines above block”
//time.Sleep(100*time.Millisecond)
c<-"bar"
wg.Wait()
if got := atomic.LoadInt32(&calls);got!=1 {
t.Errorf("number of calls = %d;want 1",got)
}
}
</pre>
在singleflight.go中func Do中对map key做了删除,如果不sleep,goruntine1 中执行fn获取了chan c的"bar", 然后删除"key"后,goruntine2 抢到锁发现map中没有"key" 会再次执行fn ,chan c 已无数据输入 ;如果sleep, goruntine1 执行fn时等待chan c的输入数据,阻塞,不会删除"key" ,其他几个 goruntine 也会发现map中有"key",所以test pass
#1