package locker import ( "fmt" "math/rand" "sync" "testing" "time" ) type Runner struct { lock *Locker res sync.Map } func NewRunner() *Runner { return &Runner{ lock: NewLocker(), } } func (r *Runner) Run(wg *sync.WaitGroup, resName string, t *testing.T) { for n := 2; n < 1000; n++ { r.lock.WaitAndLock(resName) val := fmt.Sprintf("%d", n) r.res.Store(resName, val) td := time.Duration(rand.Uint64()%1000 + 1) time.Sleep(td * time.Nanosecond) foo, exist := r.res.Load(resName) if !exist { t.Errorf("not exist!\n") } if foo != val { t.Errorf("not val!\n") } r.res.Delete(resName) r.lock.Done(resName) time.Sleep(1 * time.Millisecond) } wg.Done() } func TestLocker(t *testing.T) { run := NewRunner() var wg sync.WaitGroup for n := 1; n < 200; n++ { go run.Run(&wg, "foo", t) wg.Add(1) } for n := 1; n < 200; n++ { go run.Run(&wg, "foo/bare", t) wg.Add(1) } for n := 1; n < 200; n++ { go run.Run(&wg, "foo/bare/foo", t) wg.Add(1) } wg.Wait() }