GO_并发编程---定时器 前置说明Gotime包提供两类定时器底层均基于通道chan实现阻塞等待Timer一次性定时器时间到仅触发 1 次支持手动停止、重置倒计时Ticker周期性打点器每隔固定时间自动循环触发只能手动停止无 Reset一、一次性定时器 time.Timer1. 基础结构gotype Timer struct { C -chan Time // 只读通道时间到自动写入当前时间 r runtimeTimer }创建语法gotimer : time.NewTimer(时长) // 示例2秒定时器 timer : time.NewTimer(2 * time.Second)核心特性定时器到期后只会向timer.C写入一次时间通道只会有 1 条数据读完后无新数据再次读取会永久阻塞死锁。2. 基础使用等待定时器到期写法 1NewTimer 标准用法gopackage main import ( fmt time ) func main() { timer : time.NewTimer(2 * time.Second) fmt.Println(当前时间, time.Now()) // 阻塞读取通道时间未到则卡住 t : -timer.C fmt.Println(时间到触发时间, t) }写法 2time.After 简化延时底层封装 NewTimer适合只需要一次性延时、不需要停止 / 重置定时器的场景gopackage main import ( fmt time ) func main() { // 阻塞2秒 -time.After(2 * time.Second) fmt.Println(2秒延时结束) }注意time.After无法手动停止高频循环中反复调用会大量创建定时器增加 GC 压力推荐复用NewTimer。3. Timer 核心方法 Stop () 停止定时器作用倒计时未结束时终止定时器不再向通道发送数据返回值booltrue定时器正常停止未到期false定时器已经到期 / 已停止停止失败示例提前终止定时器子协程永远阻塞gopackage main import ( fmt time ) func main() { timer : time.NewTimer(3 * time.Second) go func() { -timer.C // 永远读不到数据阻塞 fmt.Println(子协程打印) }() // 直接停止定时器 ok : timer.Stop() fmt.Println(停止结果, ok) for {} // 阻塞主协程观察效果 }4. Timer 核心方法 Reset (d Duration) 重置倒计时作用修改定时器剩余时长重新开始倒计时返回值规则同 Stoptrue重置前定时器还在运行未到期false定时器已到期 / 已停止gopackage main import ( fmt time ) func main() { timer : time.NewTimer(3 * time.Second) time.Sleep(1 * time.Second) // 重置为1秒倒计时 ok : timer.Reset(1 * time.Second) fmt.Println(重置前定时器是否运行, ok) t : -timer.C fmt.Println(重置后触发时间, t) }5. 易错点Timer 只会触发一次定时器到期后通道仅写入 1 次数据循环读取会死锁go// 错误示例会永久阻塞 timer : time.NewTimer(2 * time.Second) for { -timer.C fmt.Println(时间到) }如需循环定时两种方案每次循环调用timer.Reset()改用Ticker周期打点器二、周期打点器 time.Ticker循环定时1. 基础特性每隔指定时长自动重复触发持续往ticker.C写入时间无 Reset 方法只能调用Stop()彻底关闭循环不手动 Stop 会持续占用资源用完必须停止创建语法goticker : time.NewTicker(间隔时长)2. 完整示例循环计数达到次数停止打点器gopackage main import ( fmt time ) func main() { // 每秒触发一次 ticker : time.NewTicker(1 * time.Second) i : 0 for { -ticker.C i fmt.Println(计数 i , i) // 执行5次后停止打点器退出循环 if i 5 { ticker.Stop() break } } fmt.Println(打点器已停止) }三、Timer vs Ticker 核心对比总结表格特性time.Timertime.Ticker触发次数仅 1 次一次性无限循环周期触发重置支持 Reset ()不支持 Reset停止Stop ()未到期返回 trueStop ()直接终止循环适用场景延时等待、超时控制定时轮询、周期任务简化写法time.After(d)无简化函数四、复习速记要点Timer 是一次性定时器时间到仅向 C 通道写入一次时间重复读取会死锁time.After(d)底层是 NewTimer适合简单延时无法手动停止timer.Stop()提前终止倒计时timer.Reset()重新修改倒计时时长Ticker 循环定时每隔固定时间自动触发用完必须调用 Stop 释放资源两者均基于通道阻塞实现等待读取通道前程序会卡住。