一、什么是定时器?
Go定时器是并发编程中的关键组件,主要用于在指定时间点或定期执行任务。它采用高效的最小堆算法实现,并与调度器进行了深度集成。
二、定时器类型与基础用法
1)一次性定时器
(1)创建定时器
创建一次性定时器,代码示例如下:
func main() {timer1 := time.NewTimer(2 * time.Second)t1 := time.Now()fmt.Printf("timer1:%v\n", t1)t2 := <-timer1.Cfmt.Printf("timer2:%v\n", t2)
}
运行结果如下图所示:
(2)停止定时器
取消已启动但尚未触发的定时器。代码示例如下:
func main() {timer1 := time.NewTimer(2 * time.Second)t1 := time.Now()fmt.Printf("timer1:%v\n", t1)timer1.Stop()
}
(3)重置定时器
重置已启动但尚未触发的定时器,但是需要注意重置定时器时需要判断定时器是否未停止。代码示例如下:
func main() {timer1 := time.NewTimer(2 * time.Second)t1 := time.Now()fmt.Printf("timer1:%v\n", t1)if !timer1.Stop() {// 排除可能的事件<-timer1.C}timer1.Reset(3 * time.Second)t2 := <-timer1.Cfmt.Printf("timer2:%v\n", t2)
}
运行结果如下图所示:
(4)延时功能
提高代码延时的三种实现方式:
- 通过time.sleep()函数实现
- 使用time.NewTimer()方法实现
- 采用time.After()函数实现
代码示例如下:
func main() {time.Sleep(time.Second)fmt.Printf("1秒到:%v\n", time.Now())timer3 := time.NewTimer(2 * time.Second)<-timer3.Cfmt.Printf("2秒到:%v\n", time.Now())<-time.After(2 * time.Second)fmt.Printf("2秒到:%v\n", time.Now())
}
(5)异步回调
使用AfterFunc 方法异步回调,无需显式等待。代码示例如下:
func main() {t1 := time.Now()fmt.Printf("timer1:%v\n", t1)time.AfterFunc(2*time.Second, func() {fmt.Printf("timer2:%v\n", time.Now())})// 阻塞主进程不退出,为定时器执行提供执行时间time.Sleep(100 * time.Second)
}
2)周期性定时器
(1)创建定时器
使用NewTicker方法创建周期性定时器,代码示例如下:
func main() {ticker := time.NewTicker(1 * time.Second)for range ticker.C {fmt.Println(time.Now())}}
运行结果如下图所示:
(2)结束定时器
周期性定时器必须显式结束,避免资源泄露。代码示例如下:
func main() {ticker := time.NewTicker(1 * time.Second)defer ticker.Stop()for range ticker.C {fmt.Println(time.Now())}}
(3)重置定时器
重置已启动周期性定时器。代码示例如下:
func main() {ticker := time.NewTicker(1 * time.Second)defer ticker.Stop()go func() {for range ticker.C {fmt.Println(time.Now())}}()time.Sleep(2 * time.Second)ticker.Reset(2 * time.Second)for {}}
运行结果如下图所示: