295
13
303

examples/module2/condition/main.go 中的队列 Dequeue 方法中,使用 if 进行条件检查:

func (q *Queue) Dequeue() string {
    q.cond.L.Lock()
    defer q.cond.L.Unlock()
    if len(q.queue) == 0 {
        fmt.Println("no data available, wait")
        q.cond.Wait()
    }
    ...

建议改成使用 for 循环判断,避免多线程的情况下 Wait() 返回时条件已经变化:

    for len(q.queue) == 0 {
        fmt.Println("no data available, wait")
        q.cond.Wait()
    }

例子中执行 Dequeue 的 goroutine 只有一个因此没有影响,本地试了下改成3个 goroutine 时就会出问题:

❯ go run main.go
no data available, wait
putting a to queue, notify all
no data available, wait
no data available, wait
no data available, wait
putting a to queue, notify all
panic: runtime error: index out of range [0] with length 0

goroutine 20 [running]:
main.(*Queue).Dequeue(0xc0000ba000)
	/home/jarvis/go/src/github.com/cncamp/golang/examples/module2/condition/main.go:52 +0x170
main.main.func2()
	/home/jarvis/go/src/github.com/cncamp/golang/examples/module2/condition/main.go:29 +0x25
created by main.main
	/home/jarvis/go/src/github.com/cncamp/golang/examples/module2/condition/main.go:27 +0x105
exit status 2