定时器与计时器
在Go语言中,定时器和计时器都出自 time 包:定时器(time.Timer)管单次延迟,计时器(time.Ticker)管周期重复。名字相近,用途不同。
1. 定时器(Timer)
time.Timer 是 Go 的 time 包中的一个类型,用于在指定的时间后执行一次操作。它用于设置一个单次延迟。
主要功能:
- 延迟执行一次操作
- 等待指定的时间间隔后触发事件
创建定时器:
time.NewTimer函数用于创建一个新的定时器,定时器将在指定的时间间隔后触发。主要方法:
Stop():停止定时器。如果定时器还未触发,调用此方法将取消其触发。Reset(d time.Duration):重置定时器,将其间隔时间设置为新的值。
示例代码:
gopackage main import ( "fmt" "time" ) func main() { // 创建一个定时器 timer := time.NewTimer(2 * time.Second) // 等待定时器触发 <-timer.C fmt.Println("定时器触发了") // 创建一个定时器并立即停止 timer2 := time.NewTimer(1 * time.Second) timer2.Stop() // 立即停止定时器 // 尝试接收定时器的触发信号 select { case <-timer2.C: fmt.Println("定时器2触发了") default: fmt.Println("定时器2被停止了") } }
2. 计时器(Ticker)
time.Ticker 是 Go 的 time 包中的一个类型,用于周期性地执行操作。它在指定的时间间隔内重复触发事件,适合用于需要重复执行某个任务的场景。
主要功能:
- 按指定时间间隔重复触发操作
- 可以用于定时任务和周期性事件
创建计时器:
time.NewTicker函数用于创建一个新的计时器,计时器会在指定的时间间隔内重复触发。主要方法:
Stop():停止计时器,取消其后续触发事件。
示例代码:
gopackage main import ( "fmt" "time" ) func main() { // 创建一个计时器,每秒触发一次 ticker := time.NewTicker(1 * time.Second) quit := make(chan struct{}) go func() { for { select { case t := <-ticker.C: fmt.Println("计时器触发时间:", t) case <-quit: ticker.Stop() return } } }() // 运行 5 秒钟后停止计时器 time.Sleep(5 * time.Second) quit <- struct{}{} fmt.Println("计时器停止了") }
3. 定时器与计时器的区别
触发方式:
- 定时器:只触发一次,在指定时间后执行操作。
- 计时器:周期性地触发,按指定时间间隔重复执行操作。
使用场景:
- 定时器:适用于一次性任务,例如延迟执行某个操作。
- 计时器:适用于周期性任务,例如定时刷新状态、定时轮询等。
实现机制:
- 定时器:通过
<-time.Timer.C接收一次性触发信号。 - 计时器:通过
<-time.Ticker.C接收周期性触发信号,并通过Stop()停止触发。
- 定时器:通过
4. 实际应用场景
定时器:
- 延迟执行任务:例如,在请求超时后进行重试。
- 延迟消息发送:例如,发送确认邮件的延迟。
计时器:
- 定时任务:例如,定期检查服务状态。
- 周期性事件:例如,定时更新应用的用户界面或数据。
总结
选哪个看节奏:等一次的用 Timer,到点从 <-timer.C 取信号,不想要了就 Stop();按固定间隔重复的用 Ticker,用完同样要 Stop(),否则事件会一直发。超时重试归 Timer,定时轮询、状态刷新归 Ticker。