问题1:下面代码输出什么
package main
import (
"fmt"
"time"
)
func main() {
// 创建两个定时器,一个间隔为1秒,另一个间隔为2秒
ticker1 := time.NewTicker(1 * time.Second)
ticker2 := time.NewTicker(2 * time.Second)
// 在一个新的 goroutine 中运行监听逻辑
go func() {
for {
select {
case t1 := <-ticker1.C:
fmt.Println("1s ticker:", t1)
case t2 := <-ticker2.C:
fmt.Println("2s ticker:", t2)
default:
fmt.Println("default")
}
}
}()
// 主函数运行一段时间
time.Sleep(5 * time.Second)
fmt.Println("Done")
}
问题2:如果加上一行代码呢
package main
import (
"fmt"
"time"
)
func main() {
// 创建两个定时器,一个间隔为1秒,另一个间隔为2秒
ticker1 := time.NewTicker(1 * time.Second)
ticker2 := time.NewTicker(2 * time.Second)
// 在一个新的 goroutine 中运行监听逻辑
go func() {
for {
select {
case t1 := <-ticker1.C:
fmt.Println("1s ticker:", t1)
case t2 := <-ticker2.C:
fmt.Println("2s ticker:", t2)
default:
fmt.Println("default")
//加上这一行
time.Sleep(1 * time.Second)
}
}
}()
// 主函数运行一段时间
time.Sleep(5 * time.Second)
fmt.Println("Done")
}
问题1的答案是会一直输出default,直到5s结束
问题2的答案是交替运行
default
1s ticker: 2024-11-13 13:37:09.5503567 +0800 CST m=+1.000307501
default
2s ticker: 2024-11-13 13:37:10.5503405 +0800 CST m=+2.000307501
1s ticker: 2024-11-13 13:37:10.5503405 +0800 CST m=+2.000307501
default
1s ticker: 2024-11-13 13:37:11.5503246 +0800 CST m=+3.000307501
default
2s ticker: 2024-11-13 13:37:12.5503087 +0800 CST m=+4.000307501
1s ticker: 2024-11-13 13:37:12.5503087 +0800 CST m=+4.000307501
default
Done
原因
select 语句中的 default 情况会执行是因为 select 语句默认会阻塞,直到其监听的通道中有数据可读。
如果没有通道准备好,select 就不会进入任何一个 case,而是继续阻塞等待。
default 分支没有被设计为在特定条件下退出循环,因此它会不断地打印 "default"