原文链接,可获取更多Go语言学习资料
在日常开发中,我们不可避免的需要使用到定时任务用来处理业务逻辑。在Go语言中内置的有两个定时器,Timer
和Ticker
,合理的使用这两个定时器可以很好的解决定时任务的需求,同时除了这两个内置的定时器外,还有另外的三方库也可以用来完成定时任务的需求。
Timer
定时器可以在指定时间后执行一次,使用time
包中的NewTimer
方法传入间隔时间参数即可创建一个Timer
定时器,定时器将会在指定的时间后执行一次。
Timer
中共有以下方法可调用
// 创建
func NewTimer(d Duration) *Timer
// 重置
func (t *Timer) Reset(d Duration) bool
// 停止
func (t *Timer) Stop() bool
在Timer
中除了有以上方法之外,还有最重要的就是Timer
中包含一个时间类型的通道C
,当指定时间间隔到达后,就会将当前时间发送到通道C
中,这样我们可以使用select
监听通道C
即可完成在指定时间后执行任务的需求。
我们根据上面的描述,完成了下面的代码:
func main() {
// 创建一个Timer定时器
timer := time.NewTimer(time.Second * 2)
// 延迟关闭定时器
defer timer.Stop()
fmt.Println("当前时间:", time.Now())
select {
// 使用select监听通道C
case nowTime := <-timer.C:
fmt.Println("间隔2秒后指定定时任务,当前时间:", nowTime)
}
}
在idea中运行代码后会输出以下内容:
当前时间: 2024-06-30 15:12:08.7736065 +0800 CST m=+0.002108801
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:12:10.7797079 +0800 CST m=+2.008210201
Process finished with the exit code 0
可以看到,Timer
定时器在指定时间后会执行一次任务,然后结束。
在上面的代码中可以看到Timer
在指定时间后仅能执行一次任务,但是我们可以使用Reset
方法重置定时器,这样的话可以在每次执行任务后重置,用来达到每间隔指定时间都执行一次任务的需求。
将代码略做修改如下:
func main() {
// 创建一个Timer定时器
timer := time.NewTimer(time.Second * 2)
// 延迟关闭定时器
defer timer.Stop()
fmt.Println("当前时间:", time.Now())
for {
timer.Reset(time.Second * 2)
select {
// 使用select监听通道C
case nowTime := <-timer.C:
fmt.Println("间隔2秒后指定定时任务,当前时间:", nowTime)
}
}
}
在上面代码中可以看到在每次的循环中都重置一次Timer
定时器,这样的话就可以实现每隔一段时间都执行一次任务的需求。
最终运行结果如下:
当前时间: 2024-06-30 15:16:01.2907834 +0800 CST m=+0.002052801
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:16:03.3096846 +0800 CST m=+2.020954001
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:16:05.3236498 +0800 CST m=+4.034919201
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:16:07.3318153 +0800 CST m=+6.043084701
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:16:09.3462966 +0800 CST m=+8.057566001
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:16:11.3504773 +0800 CST m=+10.061746701
……
Ticker
定时器的用法和Timer
定时器的用法以及内置的方法都一样,区别在于Ticker
不仅仅只执行一次,而是会根据指定的时间间隔不停地执行。
代码如下:
func main() {
ticker := time.NewTicker(time.Second * 2)
defer ticker.Stop()
fmt.Println("当前时间:", time.Now())
for {
select {
case nowTime := <-ticker.C:
fmt.Println("间隔2秒后指定定时任务,当前时间:", nowTime)
}
}
}
根据Ticker
写出以上代码,代码会每隔2
秒执行一次,不需要像Timer
中那样每次使用Reset
方法来重置定时器,最终运行结果如下:
当前时间: 2024-06-30 15:20:27.4070592 +0800 CST m=+0.002137901
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:20:29.4083801 +0800 CST m=+2.003458801
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:20:31.414517 +0800 CST m=+4.009595701
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:20:33.4191099 +0800 CST m=+6.014188601
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:20:35.4099723 +0800 CST m=+8.005051001
间隔2秒后指定定时任务,当前时间: 2024-06-30 15:20:37.4208446 +0800 CST m=+10.015923301
……
在Ticker
定时器中同样也有Reset
方法,但是就算不调用Reset
方法定时器也会一直执行,所以这里的Reset
方法可以用来重置定时器的间隔时间。
Ticker
定时器表示每隔一段时间就执行一次,一般可执行多次。Timer
定时器表示在一段时间后执行,默认情况下只执行一次,如果想再次执行的话,每次都需要调用Reset
方法,此时效果类似Ticker
定时器。同时也可以调用Stop
方法取消定时器。