分享一个select+定时器的一个代码

问题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"
posted @ 2024-11-13 13:55  朝阳1  阅读(0)  评论(0编辑  收藏  举报