1.说明
首先说明一下非缓冲channel和缓冲channel
golang中用make创建channel时,可以传入一个数值,用于指定channel的容量,这样的channel就是一个缓冲channel
// 非缓冲channel
var channel1 = make(chan int)
// 缓冲channel(容量为1)
var channel2 = make(chan int ,1)
2.案例分析
创建一个demo2.go文件
package main
import "fmt"
var channel1 chan int
var channel2 = make(chan int)
var channel3 chan int
func main() {
select {
case channel1 <- 1:
fmt.Println("channel1放入了一个值")
case channel2 <- 2:
fmt.Println("channel2放入了一个值")
case channel3 <- 3:
fmt.Println("channel3放入了一个值")
default:
fmt.Println("没有进入任何case")
}
}
go run demo2.go输出结果如下
laptop@localhost go_study % go run demo2.go
没有进入任何case
将channel2的申明方式改为
var channel2 = make(chan int ,1)
go run demo2.go输出结果如下
laptop@localhost go_study % go run demo2.go
channel2放入了一个值
可以看到非缓冲channel的select总是进入default(即没有case符合条件),缓存channel顺利的进入了case
3.问题解析
select执行有如下规则:
- select中所有的case如果存在运算符,则会按照case的顺序从上到下依次计算求得结果,然后根据是否符合条件,进入符合条件的case,如果存在多个符合条件的case,select会采用伪随机算法,选择一个case进入
- 针对非缓冲channel或者channel为nil的,case会一直阻塞。select在所有的case都阻塞或者不满足条件的情况下,会进入default